Imported Upstream version 1.72.0
[platform/upstream/boost.git] / libs / filesystem / test / path_test.cpp
1 //  path_test program  -----------------------------------------------------------------//
2
3 //  Copyright Beman Dawes 2002, 2008
4 //  Copyright Vladimir Prus 2002
5
6 //  Use, modification, and distribution is subject to the Boost Software
7 //  License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
8 //  http://www.boost.org/LICENSE_1_0.txt)
9
10 //  See library home page at http://www.boost.org/libs/filesystem
11
12 //  basic_path's stem(), extension(), and replace_extension() tests are based
13 //  on basename(), extension(), and change_extension() tests from the original
14 //  convenience_test.cpp by Vladimir Prus.
15
16 //--------------------------------------------------------------------------------------//
17 //                                                                                      //
18 //                                     Caution                                          //
19 //                                                                                      //
20 //  The class path relational operators (==, !=, <, etc.) on Windows treat slash and    //
21 //  backslash as equal. Thus any tests on Windows where the difference between slash    //
22 //  and backslash is significant should compare strings rather than paths.              //
23 //                                                                                      //
24 //  BOOST_TEST(path == path)                     // '\\' and '/' are equal              //
25 //  BOOST_TEST(path == convertable to string)    // '\\' and '/' are equal              //
26 //  PATH_TEST_EQ(path, path)                     // '\\' and '/' are equal              //
27 //                                                                                      //
28 //  BOOST_TEST(path.string() == path.string())   // '\\' and '/' are not equal          //
29 //  BOOST_TEST(path.string() ==                                                         //
30 //               convertable to string)          // '\\' and '/' are not equal          //
31 //  PATH_TEST_EQ(path.string(),                                                         //
32 //                convertable to string)         // '\\' and '/' are not equal          //
33 //                                                                                      //
34 //  The last of these is often what is needed, so the PATH_TEST_EQ macro is provided.   //
35 //  It converts its first argument to a path, and then performs a .string() on it,      //
36 //  eliminating much boilerplate .string() or even path(...).string() code.             //
37 //                                                                                      //
38 //  PATH_TEST_EQ(path, convertable to string)    // '\\' and '/' are not equal          //
39 //                                                                                      //
40 //--------------------------------------------------------------------------------------//
41
42 #include <boost/config/warning_disable.hpp>
43
44 //  See deprecated_test for tests of deprecated features
45 #ifndef BOOST_FILESYSTEM_NO_DEPRECATED
46 #  define BOOST_FILESYSTEM_NO_DEPRECATED
47 #endif
48 #ifndef BOOST_SYSTEM_NO_DEPRECATED
49 #  define BOOST_SYSTEM_NO_DEPRECATED
50 #endif
51
52 #include <boost/filesystem/operations.hpp>
53 #include <boost/filesystem/exception.hpp>
54
55 #include <boost/config.hpp>
56 # if defined( BOOST_NO_STD_WSTRING )
57 #   error Configuration not supported: Boost.Filesystem V3 and later requires std::wstring support
58 # endif
59
60 #include <boost/utility.hpp>
61 #include <boost/next_prior.hpp>
62 #include <iostream>
63 #include <sstream>
64 #include <string>
65 #include <vector>
66 #include <cstring>
67 #include <cassert>
68 #include <boost/detail/lightweight_test.hpp>
69 #include <boost/detail/lightweight_main.hpp>
70
71 namespace fs = boost::filesystem;
72 using boost::filesystem::path;
73 using boost::next;
74 using boost::prior;
75
76 #ifdef BOOST_WINDOWS_API
77 # define BOOST_DIR_SEP "\\"
78 #else
79 # define BOOST_DIR_SEP "/"
80 #endif
81
82 #define PATH_TEST_EQ(a, b) check(a, b, __FILE__, __LINE__)
83
84 namespace
85 {
86   std::string platform(BOOST_PLATFORM);
87
88   void check(const fs::path & source,
89               const std::string & expected, const char* file, int line)
90   {
91     if (source.string() == expected)
92       return;
93
94     std::cout << file
95               << '(' << line << "): source: \"" << source.string()
96               << "\" != expected: \"" << expected
97               << "\"" << std::endl;
98
99     ++::boost::detail::test_errors();
100   }
101
102   path p1("fe/fi/fo/fum");
103   path p2(p1);
104   path p3;
105   path p4("foobar");
106   path p5;
107
108   //  exception_tests  -----------------------------------------------------------------//
109
110   void exception_tests()
111   {
112     std::cout << "exception_tests..." << std::endl;
113     const std::string str_1("string-1");
114     boost::system::error_code ec(12345, boost::system::system_category());
115     try { throw fs::filesystem_error(str_1, ec); }
116     catch (const fs::filesystem_error & ex)
117     {
118       //std::cout << ex.what() << "*" << std::endl;
119       //BOOST_TEST(std::strcmp(ex.what(),
120       //  "string-1: Unknown error") == 0);
121       BOOST_TEST(ex.code() == ec);
122     }
123
124     try { throw fs::filesystem_error(str_1, "p1", "p2", ec); }
125     catch (const fs::filesystem_error & ex)
126     {
127       //std::cout << ex.what() << "*" << std::endl;
128       //BOOST_TEST(std::strcmp(ex.what(),
129       //  "string-1: Unknown error: \"p1\", \"p2\"") == 0);
130       BOOST_TEST(ex.code() == ec);
131       BOOST_TEST(ex.path1() == "p1");
132       BOOST_TEST(ex.path2() == "p2");
133     }
134   }
135
136   //  overload_tests  ------------------------------------------------------------------//
137
138   // These verify various overloads don't cause compiler errors
139   // They pre-date operations_unit_test.cpp
140
141   void overload_tests()
142   {
143     std::cout << "overload_tests..." << std::endl;
144
145     fs::exists(p1);
146     fs::exists("foo");
147     fs::exists(std::string("foo"));
148
149     fs::exists(p1 / path("foo"));
150     fs::exists(p1 / "foo");
151     fs::exists(p1 / std::string("foo"));
152
153     fs::exists("foo" / p1);
154     fs::exists(std::string("foo") / p1);
155
156     p4 /= path("foo");
157     p4 /= "foo";
158     p4 /= std::string("foo");
159   }
160
161   //  iterator_tests  ------------------------------------------------------------------//
162
163   void iterator_tests()
164   {
165     std::cout << "iterator_tests..." << std::endl;
166
167     path itr_ck = "";
168     path::const_iterator itr = itr_ck.begin();
169     BOOST_TEST(itr == itr_ck.end());
170
171     itr_ck = "/";
172     itr = itr_ck.begin();
173     BOOST_TEST(itr->string() == "/");
174     BOOST_TEST(++itr == itr_ck.end());
175     BOOST_TEST((--itr)->string() == "/");
176
177     itr_ck = "foo";
178     BOOST_TEST(*itr_ck.begin() == std::string("foo"));
179     BOOST_TEST(boost::next(itr_ck.begin()) == itr_ck.end());
180     BOOST_TEST(*boost::prior(itr_ck.end()) == std::string("foo"));
181     BOOST_TEST(boost::prior(itr_ck.end()) == itr_ck.begin());
182
183     itr_ck = path("/foo");
184     BOOST_TEST((itr_ck.begin())->string() == "/");
185     BOOST_TEST(*boost::next(itr_ck.begin()) == std::string("foo"));
186     BOOST_TEST(boost::next(boost::next(itr_ck.begin())) == itr_ck.end());
187     BOOST_TEST(boost::next(itr_ck.begin()) == boost::prior(itr_ck.end()));
188     BOOST_TEST(*boost::prior(itr_ck.end()) == std::string("foo"));
189     BOOST_TEST(*boost::prior(boost::prior(itr_ck.end())) == std::string("/"));
190     BOOST_TEST(boost::prior(boost::prior(itr_ck.end())) == itr_ck.begin());
191
192     itr_ck = "/foo/bar";
193     itr = itr_ck.begin();
194     BOOST_TEST(itr->string() == "/");
195     BOOST_TEST(*++itr == std::string("foo"));
196     BOOST_TEST(*++itr == std::string("bar"));
197     BOOST_TEST(++itr == itr_ck.end());
198     PATH_TEST_EQ(*--itr, "bar");
199     PATH_TEST_EQ(*--itr, "foo");
200     PATH_TEST_EQ(*--itr, "/");
201
202     itr_ck = "../f"; // previously failed due to short name bug
203     itr = itr_ck.begin();
204     PATH_TEST_EQ(itr->string(), "..");
205     PATH_TEST_EQ(*++itr, "f");
206     BOOST_TEST(++itr == itr_ck.end());
207     PATH_TEST_EQ(*--itr, "f");
208     PATH_TEST_EQ(*--itr, "..");
209
210     // POSIX says treat "/foo/bar/" as "/foo/bar/."
211     itr_ck = "/foo/bar/";
212     itr = itr_ck.begin();
213     PATH_TEST_EQ(itr->string(), "/");
214     PATH_TEST_EQ(*++itr, "foo");
215     BOOST_TEST(itr != itr_ck.end());
216     PATH_TEST_EQ(*++itr, "bar");
217     BOOST_TEST(itr != itr_ck.end());
218     PATH_TEST_EQ(*++itr, ".");
219     BOOST_TEST(itr != itr_ck.end());  // verify the . isn't also seen as end()
220     BOOST_TEST(++itr == itr_ck.end());
221     PATH_TEST_EQ(*--itr, ".");
222     PATH_TEST_EQ(*--itr, "bar");
223     PATH_TEST_EQ(*--itr, "foo");
224     PATH_TEST_EQ(*--itr, "/");
225
226     // POSIX says treat "/f/b/" as "/f/b/."
227     itr_ck = "/f/b/";
228     itr = itr_ck.begin();
229     PATH_TEST_EQ(itr->string(), "/");
230     PATH_TEST_EQ(*++itr, "f");
231     PATH_TEST_EQ(*++itr, "b");
232     PATH_TEST_EQ(*++itr, ".");
233     BOOST_TEST(itr != itr_ck.end());  // verify the . isn't also seen as end()
234     BOOST_TEST(++itr == itr_ck.end());
235     PATH_TEST_EQ(*--itr, ".");
236     PATH_TEST_EQ(*--itr, "b");
237     PATH_TEST_EQ(*--itr, "f");
238     PATH_TEST_EQ(*--itr, "/");
239
240     // POSIX says treat "a/b/" as "a/b/."
241     // Although similar to the prior test case, this failed the ". isn't end" test due to
242     // a bug while the prior case did not fail.
243     itr_ck = "a/b/";
244     itr = itr_ck.begin();
245     PATH_TEST_EQ(*itr, "a");
246     PATH_TEST_EQ(*++itr, "b");
247     PATH_TEST_EQ(*++itr, ".");
248     BOOST_TEST(itr != itr_ck.end());  // verify the . isn't also seen as end()
249     BOOST_TEST(++itr == itr_ck.end());
250     PATH_TEST_EQ(*--itr, ".");
251     PATH_TEST_EQ(*--itr, "b");
252     PATH_TEST_EQ(*--itr, "a");
253
254     itr_ck = "//net";
255     itr = itr_ck.begin();
256     // two leading slashes are permitted by POSIX (as implementation defined),
257     // while for Windows it is always well defined (as a network name)
258     PATH_TEST_EQ(itr->string(), "//net");
259     BOOST_TEST(++itr == itr_ck.end());
260     PATH_TEST_EQ(*--itr, "//net");
261
262     itr_ck = "//net/";
263     itr = itr_ck.begin();
264     PATH_TEST_EQ(itr->string(), "//net");
265     PATH_TEST_EQ(*++itr, "/");
266     BOOST_TEST(++itr == itr_ck.end());
267     PATH_TEST_EQ(*--itr, "/");
268     PATH_TEST_EQ(*--itr, "//net");
269
270     itr_ck = "//foo///bar///";
271     itr = itr_ck.begin();
272     PATH_TEST_EQ(itr->string(), "//foo");
273     PATH_TEST_EQ(*++itr, "/");
274     PATH_TEST_EQ(*++itr, "bar");
275     PATH_TEST_EQ(*++itr, ".");
276     BOOST_TEST(++itr == itr_ck.end());
277     PATH_TEST_EQ(*--itr, ".");
278     PATH_TEST_EQ(*--itr, "bar");
279     PATH_TEST_EQ(*--itr, "/");
280     PATH_TEST_EQ(*--itr, "//foo");
281
282     itr_ck = "///foo///bar///";
283     itr = itr_ck.begin();
284     // three or more leading slashes are to be treated as a single slash
285     PATH_TEST_EQ(itr->string(), "/");
286     PATH_TEST_EQ(*++itr, "foo");
287     PATH_TEST_EQ(*++itr, "bar");
288     PATH_TEST_EQ(*++itr, ".");
289     BOOST_TEST(++itr == itr_ck.end());
290     PATH_TEST_EQ(*--itr, ".");
291     PATH_TEST_EQ(*--itr, "bar");
292     PATH_TEST_EQ(*--itr, "foo");
293     PATH_TEST_EQ(*--itr, "/");
294
295     if (platform == "Windows")
296     {
297       itr_ck = "c:/";
298       itr = itr_ck.begin();
299       PATH_TEST_EQ(itr->string(), "c:");
300       PATH_TEST_EQ(*++itr, std::string("/"));
301       BOOST_TEST(++itr == itr_ck.end());
302       PATH_TEST_EQ(*--itr, "/");
303       PATH_TEST_EQ(*--itr, "c:");
304
305       itr_ck = "c:\\";
306       itr = itr_ck.begin();
307       PATH_TEST_EQ(itr->string(), "c:");
308       PATH_TEST_EQ(*++itr, "/");  // test that iteration returns generic format
309       BOOST_TEST(++itr == itr_ck.end());
310       PATH_TEST_EQ(*--itr, "/");  // test that iteration returns generic format
311       PATH_TEST_EQ(*--itr, "c:");
312
313       itr_ck = "c:/foo";
314       itr = itr_ck.begin();
315       BOOST_TEST(*itr == std::string("c:"));
316       BOOST_TEST(*++itr == std::string("/"));
317       BOOST_TEST(*++itr == std::string("foo"));
318       BOOST_TEST(++itr == itr_ck.end());
319       BOOST_TEST(*--itr == std::string("foo"));
320       BOOST_TEST((--itr)->string() == "/");
321       BOOST_TEST(*--itr == std::string("c:"));
322
323       itr_ck = "c:\\foo";
324       itr = itr_ck.begin();
325       BOOST_TEST(*itr == std::string("c:"));
326       BOOST_TEST(*++itr == std::string("\\"));
327       BOOST_TEST(*++itr == std::string("foo"));
328       BOOST_TEST(++itr == itr_ck.end());
329       BOOST_TEST(*--itr == std::string("foo"));
330       BOOST_TEST(*--itr == std::string("\\"));
331       BOOST_TEST(*--itr == std::string("c:"));
332
333       itr_ck = "\\\\\\foo\\\\\\bar\\\\\\";
334       itr = itr_ck.begin();
335       // three or more leading slashes are to be treated as a single slash
336       PATH_TEST_EQ(itr->string(), "/");
337       PATH_TEST_EQ(*++itr, "foo");
338       PATH_TEST_EQ(*++itr, "bar");
339       PATH_TEST_EQ(*++itr, ".");
340       BOOST_TEST(++itr == itr_ck.end());
341       PATH_TEST_EQ(*--itr, ".");
342       PATH_TEST_EQ(*--itr, "bar");
343       PATH_TEST_EQ(*--itr, "foo");
344       PATH_TEST_EQ(*--itr, "/");
345
346       itr_ck = "c:foo";
347       itr = itr_ck.begin();
348       BOOST_TEST(*itr == std::string("c:"));
349       BOOST_TEST(*++itr == std::string("foo"));
350       BOOST_TEST(++itr == itr_ck.end());
351       BOOST_TEST(*--itr == std::string("foo"));
352       BOOST_TEST(*--itr == std::string("c:"));
353
354       itr_ck = "c:foo/";
355       itr = itr_ck.begin();
356       BOOST_TEST(*itr == std::string("c:"));
357       BOOST_TEST(*++itr == std::string("foo"));
358       BOOST_TEST(*++itr == std::string("."));
359       BOOST_TEST(++itr == itr_ck.end());
360       BOOST_TEST(*--itr == std::string("."));
361       BOOST_TEST(*--itr == std::string("foo"));
362       BOOST_TEST(*--itr == std::string("c:"));
363
364       itr_ck = path("c:");
365       BOOST_TEST(*itr_ck.begin() == std::string("c:"));
366       BOOST_TEST(next(itr_ck.begin()) == itr_ck.end());
367       BOOST_TEST(prior(itr_ck.end()) == itr_ck.begin());
368       BOOST_TEST(*prior(itr_ck.end()) == std::string("c:"));
369
370       itr_ck = path("c:/");
371       BOOST_TEST(*itr_ck.begin() == std::string("c:"));
372       BOOST_TEST(*next(itr_ck.begin()) == std::string("/"));
373       BOOST_TEST(next(next(itr_ck.begin())) == itr_ck.end());
374       BOOST_TEST(prior(prior(itr_ck.end())) == itr_ck.begin());
375       BOOST_TEST(*prior(itr_ck.end()) == std::string("/"));
376       BOOST_TEST(*prior(prior(itr_ck.end())) == std::string("c:"));
377
378       itr_ck = path("c:foo");
379       BOOST_TEST(*itr_ck.begin() == std::string("c:"));
380       BOOST_TEST(*next(itr_ck.begin()) == std::string("foo"));
381       BOOST_TEST(next(next(itr_ck.begin())) == itr_ck.end());
382       BOOST_TEST(prior(prior(itr_ck.end())) == itr_ck.begin());
383       BOOST_TEST(*prior(itr_ck.end()) == std::string("foo"));
384       BOOST_TEST(*prior(prior(itr_ck.end())) == std::string("c:"));
385
386       itr_ck = path("c:/foo");
387       BOOST_TEST(*itr_ck.begin() == std::string("c:"));
388       BOOST_TEST(*next(itr_ck.begin()) == std::string("/"));
389       BOOST_TEST(*next(next(itr_ck.begin())) == std::string("foo"));
390       BOOST_TEST(next(next(next(itr_ck.begin()))) == itr_ck.end());
391       BOOST_TEST(prior(prior(prior(itr_ck.end()))) == itr_ck.begin());
392       BOOST_TEST(*prior(itr_ck.end()) == std::string("foo"));
393       BOOST_TEST(*prior(prior(itr_ck.end())) == std::string("/"));
394       BOOST_TEST(*prior(prior(prior(itr_ck.end()))) == std::string("c:"));
395
396       itr_ck = path("//net");
397       BOOST_TEST(*itr_ck.begin() == std::string("//net"));
398       BOOST_TEST(next(itr_ck.begin()) == itr_ck.end());
399       BOOST_TEST(prior(itr_ck.end()) == itr_ck.begin());
400       BOOST_TEST(*prior(itr_ck.end()) == std::string("//net"));
401
402       itr_ck = path("//net/");
403       PATH_TEST_EQ(itr_ck.begin()->string(), "//net");
404       PATH_TEST_EQ(next(itr_ck.begin())->string(), "/");
405       BOOST_TEST(next(next(itr_ck.begin())) == itr_ck.end());
406       BOOST_TEST(prior(prior(itr_ck.end())) == itr_ck.begin());
407       PATH_TEST_EQ(prior(itr_ck.end())->string(), "/");
408       PATH_TEST_EQ(prior(prior(itr_ck.end()))->string(), "//net");
409
410       itr_ck = path("//net/foo");
411       BOOST_TEST(*itr_ck.begin() == std::string("//net"));
412       BOOST_TEST(*next(itr_ck.begin()) == std::string("/"));
413       BOOST_TEST(*next(next(itr_ck.begin())) == std::string("foo"));
414       BOOST_TEST(next(next(next(itr_ck.begin()))) == itr_ck.end());
415       BOOST_TEST(prior(prior(prior(itr_ck.end()))) == itr_ck.begin());
416       BOOST_TEST(*prior(itr_ck.end()) == std::string("foo"));
417       BOOST_TEST(*prior(prior(itr_ck.end())) == std::string("/"));
418       BOOST_TEST(*prior(prior(prior(itr_ck.end()))) == std::string("//net"));
419
420       itr_ck = path("prn:");
421       BOOST_TEST(*itr_ck.begin() == std::string("prn:"));
422       BOOST_TEST(next(itr_ck.begin()) == itr_ck.end());
423       BOOST_TEST(prior(itr_ck.end()) == itr_ck.begin());
424       BOOST_TEST(*prior(itr_ck.end()) == std::string("prn:"));
425     }
426     else
427     {
428       itr_ck = "///";
429       itr = itr_ck.begin();
430       PATH_TEST_EQ(itr->string(),  "/");
431       BOOST_TEST(++itr == itr_ck.end());
432     }
433   }
434
435   //  non_member_tests  ----------------------------------------------------------------//
436
437   void non_member_tests()
438   {
439     std::cout << "non_member_tests..." << std::endl;
440
441     // test non-member functions, particularly operator overloads
442
443     path e, e2;
444     std::string es, es2;
445     char ecs[] = "";
446     char ecs2[] = "";
447
448     char acs[] = "a";
449     std::string as(acs);
450     path a(as);
451
452     char acs2[] = "a";
453     std::string as2(acs2);
454     path a2(as2);
455
456     char bcs[] = "b";
457     std::string bs(bcs);
458     path b(bs);
459
460     // swap
461     a.swap(b);
462     BOOST_TEST(a.string() == "b");
463     BOOST_TEST(b.string() == "a");
464     fs::swap(a, b);
465     BOOST_TEST(a.string() == "a");
466     BOOST_TEST(b.string() == "b");
467
468     // probe operator /
469     PATH_TEST_EQ(path("") / ".", ".");
470     PATH_TEST_EQ(path("") / "..", "..");
471     if (platform == "Windows")
472     {
473       BOOST_TEST(path("foo\\bar") == "foo/bar");
474       BOOST_TEST((b / a).native() == path("b\\a").native());
475       BOOST_TEST((bs / a).native() == path("b\\a").native());
476       BOOST_TEST((bcs / a).native() == path("b\\a").native());
477       BOOST_TEST((b / as).native() == path("b\\a").native());
478       BOOST_TEST((b / acs).native() == path("b\\a").native());
479       PATH_TEST_EQ(path("a") / "b", "a\\b");
480       PATH_TEST_EQ(path("..") / "", "..");
481       PATH_TEST_EQ(path("foo") / path("bar"), "foo\\bar"); // path arg
482       PATH_TEST_EQ(path("foo") / "bar", "foo\\bar");       // const char* arg
483       PATH_TEST_EQ(path("foo") / path("woo/bar").filename(), "foo\\bar"); // const std::string & arg
484       PATH_TEST_EQ("foo" / path("bar"), "foo\\bar");
485       PATH_TEST_EQ(path("..") / ".." , "..\\..");
486       PATH_TEST_EQ(path("/") / ".." , "/..");
487       PATH_TEST_EQ(path("/..") / ".." , "/..\\..");
488       PATH_TEST_EQ(path("..") / "foo" , "..\\foo");
489       PATH_TEST_EQ(path("foo") / ".." , "foo\\..");
490       PATH_TEST_EQ(path("..") / "f" , "..\\f");
491       PATH_TEST_EQ(path("/..") / "f" , "/..\\f");
492       PATH_TEST_EQ(path("f") / ".." , "f\\..");
493       PATH_TEST_EQ(path("foo") / ".." / ".." , "foo\\..\\..");
494       PATH_TEST_EQ(path("foo") / ".." / ".." / ".." , "foo\\..\\..\\..");
495       PATH_TEST_EQ(path("f") / ".." / "b" , "f\\..\\b");
496       PATH_TEST_EQ(path("foo") / ".." / "bar" , "foo\\..\\bar");
497       PATH_TEST_EQ(path("foo") / "bar" / ".." , "foo\\bar\\..");
498       PATH_TEST_EQ(path("foo") / "bar" / ".." / "..", "foo\\bar\\..\\..");
499       PATH_TEST_EQ(path("foo") / "bar" / ".." / "blah", "foo\\bar\\..\\blah");
500       PATH_TEST_EQ(path("f") / "b" / ".." , "f\\b\\..");
501       PATH_TEST_EQ(path("f") / "b" / ".." / "a", "f\\b\\..\\a");
502       PATH_TEST_EQ(path("foo") / "bar" / "blah" / ".." / "..", "foo\\bar\\blah\\..\\..");
503       PATH_TEST_EQ(path("foo") / "bar" / "blah" / ".." / ".." / "bletch", "foo\\bar\\blah\\..\\..\\bletch");
504
505       PATH_TEST_EQ(path(".") / "foo", ".\\foo");
506       PATH_TEST_EQ(path(".") / "..", ".\\..");
507       PATH_TEST_EQ(path("foo") / ".", "foo\\.");
508       PATH_TEST_EQ(path("..") / ".", "..\\.");
509       PATH_TEST_EQ(path(".") / ".", ".\\.");
510       PATH_TEST_EQ(path(".") / "." / ".", ".\\.\\.");
511       PATH_TEST_EQ(path(".") / "foo" / ".", ".\\foo\\.");
512       PATH_TEST_EQ(path("foo") / "." / "bar", "foo\\.\\bar");
513       PATH_TEST_EQ(path("foo") / "." / ".", "foo\\.\\.");
514       PATH_TEST_EQ(path("foo") / "." / "..", "foo\\.\\..");
515       PATH_TEST_EQ(path(".") / "." / "..", ".\\.\\..");
516       PATH_TEST_EQ(path(".") / ".." / ".", ".\\..\\.");
517       PATH_TEST_EQ(path("..") / "." / ".", "..\\.\\.");
518     }
519     else  // POSIX
520     {
521       PATH_TEST_EQ(b / a, "b/a");
522       PATH_TEST_EQ(bs / a, "b/a");
523       PATH_TEST_EQ(bcs / a, "b/a");
524       PATH_TEST_EQ(b / as, "b/a");
525       PATH_TEST_EQ(b / acs, "b/a");
526       PATH_TEST_EQ(path("a") / "b", "a/b");
527       PATH_TEST_EQ(path("..") / "", "..");
528       PATH_TEST_EQ(path("") / "..", "..");
529       PATH_TEST_EQ(path("foo") / path("bar"), "foo/bar"); // path arg
530       PATH_TEST_EQ(path("foo") / "bar", "foo/bar");       // const char* arg
531       PATH_TEST_EQ(path("foo") / path("woo/bar").filename(), "foo/bar"); // const std::string & arg
532       PATH_TEST_EQ("foo" / path("bar"), "foo/bar");
533       PATH_TEST_EQ(path("..") / ".." , "../..");
534       PATH_TEST_EQ(path("/") / ".." , "/..");
535       PATH_TEST_EQ(path("/..") / ".." , "/../..");
536       PATH_TEST_EQ(path("..") / "foo" , "../foo");
537       PATH_TEST_EQ(path("foo") / ".." , "foo/..");
538       PATH_TEST_EQ(path("..") / "f" , "../f");
539       PATH_TEST_EQ(path("/..") / "f" , "/../f");
540       PATH_TEST_EQ(path("f") / ".." , "f/..");
541       PATH_TEST_EQ(path("foo") / ".." / ".." , "foo/../..");
542       PATH_TEST_EQ(path("foo") / ".." / ".." / ".." , "foo/../../..");
543       PATH_TEST_EQ(path("f") / ".." / "b" , "f/../b");
544       PATH_TEST_EQ(path("foo") / ".." / "bar" , "foo/../bar");
545       PATH_TEST_EQ(path("foo") / "bar" / ".." , "foo/bar/..");
546       PATH_TEST_EQ(path("foo") / "bar" / ".." / "..", "foo/bar/../..");
547       PATH_TEST_EQ(path("foo") / "bar" / ".." / "blah", "foo/bar/../blah");
548       PATH_TEST_EQ(path("f") / "b" / ".." , "f/b/..");
549       PATH_TEST_EQ(path("f") / "b" / ".." / "a", "f/b/../a");
550       PATH_TEST_EQ(path("foo") / "bar" / "blah" / ".." / "..", "foo/bar/blah/../..");
551       PATH_TEST_EQ(path("foo") / "bar" / "blah" / ".." / ".." / "bletch", "foo/bar/blah/../../bletch");
552
553       PATH_TEST_EQ(path(".") / "foo", "./foo");
554       PATH_TEST_EQ(path(".") / "..", "./..");
555       PATH_TEST_EQ(path("foo") / ".", "foo/.");
556       PATH_TEST_EQ(path("..") / ".", "../.");
557       PATH_TEST_EQ(path(".") / ".", "./.");
558       PATH_TEST_EQ(path(".") / "." / ".", "././.");
559       PATH_TEST_EQ(path(".") / "foo" / ".", "./foo/.");
560       PATH_TEST_EQ(path("foo") / "." / "bar", "foo/./bar");
561       PATH_TEST_EQ(path("foo") / "." / ".", "foo/./.");
562       PATH_TEST_EQ(path("foo") / "." / "..", "foo/./..");
563       PATH_TEST_EQ(path(".") / "." / "..", "././..");
564       PATH_TEST_EQ(path(".") / ".." / ".", "./../.");
565       PATH_TEST_EQ(path("..") / "." / ".", ".././.");
566     }
567
568     // probe operator <
569     BOOST_TEST(!(e < e2));
570     BOOST_TEST(!(es < e2));
571     BOOST_TEST(!(ecs < e2));
572     BOOST_TEST(!(e < es2));
573     BOOST_TEST(!(e < ecs2));
574
575     BOOST_TEST(e < a);
576     BOOST_TEST(es < a);
577     BOOST_TEST(ecs < a);
578     BOOST_TEST(e < as);
579     BOOST_TEST(e < acs);
580
581     BOOST_TEST(a < b);
582     BOOST_TEST(as < b);
583     BOOST_TEST(acs < b);
584     BOOST_TEST(a < bs);
585     BOOST_TEST(a < bcs);
586
587     BOOST_TEST(!(a < a2));
588     BOOST_TEST(!(as < a2));
589     BOOST_TEST(!(acs < a2));
590     BOOST_TEST(!(a < as2));
591     BOOST_TEST(!(a < acs2));
592
593     // make sure basic_path overloads don't conflict with std::string overloads
594
595     BOOST_TEST(!(as < as));
596     BOOST_TEST(!(as < acs));
597     BOOST_TEST(!(acs < as));
598
599     // character set reality check before lexicographical tests
600     BOOST_TEST(std::string("a.b") < std::string("a/b"));
601     // verify compare is actually lexicographical
602     BOOST_TEST(path("a/b") < path("a.b"));
603     BOOST_TEST(path("a/b") == path("a///b"));
604     BOOST_TEST(path("a/b/") == path("a/b/."));
605     BOOST_TEST(path("a/b") != path("a/b/"));
606
607     // make sure the derivative operators also work
608
609     BOOST_TEST(b > a);
610     BOOST_TEST(b > as);
611     BOOST_TEST(b > acs);
612     BOOST_TEST(bs > a);
613     BOOST_TEST(bcs > a);
614
615     BOOST_TEST(!(a2 > a));
616     BOOST_TEST(!(a2 > as));
617     BOOST_TEST(!(a2 > acs));
618     BOOST_TEST(!(as2 > a));
619     BOOST_TEST(!(acs2 > a));
620
621     BOOST_TEST(a <= b);
622     BOOST_TEST(as <= b);
623     BOOST_TEST(acs <= b);
624     BOOST_TEST(a <= bs);
625     BOOST_TEST(a <= bcs);
626
627     BOOST_TEST(a <= a2);
628     BOOST_TEST(as <= a2);
629     BOOST_TEST(acs <= a2);
630     BOOST_TEST(a <= as2);
631     BOOST_TEST(a <= acs2);
632
633     BOOST_TEST(b >= a);
634     BOOST_TEST(bs >= a);
635     BOOST_TEST(bcs >= a);
636     BOOST_TEST(b >= as);
637     BOOST_TEST(b >= acs);
638
639     BOOST_TEST(a2 >= a);
640     BOOST_TEST(as2 >= a);
641     BOOST_TEST(acs2 >= a);
642     BOOST_TEST(a2 >= as);
643     BOOST_TEST(a2 >= acs);
644
645     //  operator == and != are implemented separately, so test separately
646
647     path p101("fe/fi/fo/fum");
648     path p102(p101);
649     path p103("fe/fi/fo/fumm");
650     BOOST_TEST(p101.string() != p103.string());
651
652     // check each overload
653     BOOST_TEST(p101 != p103);
654     BOOST_TEST(p101 != p103.string());
655     BOOST_TEST(p101 != p103.string().c_str());
656     BOOST_TEST(p101.string() != p103);
657     BOOST_TEST(p101.string().c_str() != p103);
658
659     p103 = p102;
660     BOOST_TEST(p101.string() == p103.string());
661
662     // check each overload
663     BOOST_TEST(p101 == p103);
664     BOOST_TEST(p101 == p103.string());
665     BOOST_TEST(p101 == p103.string().c_str());
666     BOOST_TEST(p101.string() == p103);
667     BOOST_TEST(p101.string().c_str() == p103);
668
669     if (platform == "Windows")
670     {
671       std::cout << "  Windows relational tests..." << std::endl;
672       path p10 ("c:\\file");
673       path p11 ("c:/file");
674       // check each overload
675       BOOST_TEST(p10.generic_string() == p11.generic_string());
676       BOOST_TEST(p10 == p11);
677       BOOST_TEST(p10 == p11.string());
678       BOOST_TEST(p10 == p11.string().c_str());
679       BOOST_TEST(p10.string() == p11);
680       BOOST_TEST(p10.string().c_str() == p11);
681       BOOST_TEST(p10 == L"c:\\file");
682       BOOST_TEST(p10 == L"c:/file");
683       BOOST_TEST(p11 == L"c:\\file");
684       BOOST_TEST(p11 == L"c:/file");
685       BOOST_TEST(L"c:\\file" == p10);
686       BOOST_TEST(L"c:/file" == p10);
687       BOOST_TEST(L"c:\\file" == p11);
688       BOOST_TEST(L"c:/file" == p11);
689
690       BOOST_TEST(!(p10.generic_string() != p11.generic_string()));
691       BOOST_TEST(!(p10 != p11));
692       BOOST_TEST(!(p10 != p11.string()));
693       BOOST_TEST(!(p10 != p11.string().c_str()));
694       BOOST_TEST(!(p10.string() != p11));
695       BOOST_TEST(!(p10.string().c_str() != p11));
696       BOOST_TEST(!(p10 != L"c:\\file"));
697       BOOST_TEST(!(p10 != L"c:/file"));
698       BOOST_TEST(!(p11 != L"c:\\file"));
699       BOOST_TEST(!(p11 != L"c:/file"));
700       BOOST_TEST(!(L"c:\\file" != p10));
701       BOOST_TEST(!(L"c:/file" != p10));
702       BOOST_TEST(!(L"c:\\file" != p11));
703       BOOST_TEST(!(L"c:/file" != p11));
704
705       BOOST_TEST(!(p10.string() < p11.string()));
706       BOOST_TEST(!(p10 < p11));
707       BOOST_TEST(!(p10 < p11.string()));
708       BOOST_TEST(!(p10 < p11.string().c_str()));
709       BOOST_TEST(!(p10.string() < p11));
710       BOOST_TEST(!(p10.string().c_str() < p11));
711       BOOST_TEST(!(p10 < L"c:\\file"));
712       BOOST_TEST(!(p10 < L"c:/file"));
713       BOOST_TEST(!(p11 < L"c:\\file"));
714       BOOST_TEST(!(p11 < L"c:/file"));
715       BOOST_TEST(!(L"c:\\file" < p10));
716       BOOST_TEST(!(L"c:/file" < p10));
717       BOOST_TEST(!(L"c:\\file" < p11));
718       BOOST_TEST(!(L"c:/file" < p11));
719
720       BOOST_TEST(!(p10.generic_string() > p11.generic_string()));
721       BOOST_TEST(!(p10 > p11));
722       BOOST_TEST(!(p10 > p11.string()));
723       BOOST_TEST(!(p10 > p11.string().c_str()));
724       BOOST_TEST(!(p10.string() > p11));
725       BOOST_TEST(!(p10.string().c_str() > p11));
726       BOOST_TEST(!(p10 > L"c:\\file"));
727       BOOST_TEST(!(p10 > L"c:/file"));
728       BOOST_TEST(!(p11 > L"c:\\file"));
729       BOOST_TEST(!(p11 > L"c:/file"));
730       BOOST_TEST(!(L"c:\\file" > p10));
731       BOOST_TEST(!(L"c:/file" > p10));
732       BOOST_TEST(!(L"c:\\file" > p11));
733       BOOST_TEST(!(L"c:/file" > p11));
734     }
735
736     // relative
737
738     BOOST_TEST(fs::relative("/abc/def", "/abc") == path("def"));
739     BOOST_TEST(fs::relative("abc/def", "abc") == path("def"));
740     BOOST_TEST(fs::relative("/abc/xyz/def", "/abc") == path("xyz/def"));
741     BOOST_TEST(fs::relative("abc/xyz/def", "abc") == path("xyz/def"));
742
743     if (platform == "Windows")
744     {
745       std::cout << "  Windows relatie tests..." << std::endl;
746       BOOST_TEST(fs::relative("\\abc\\xyz\\def", "/abc") == path("xyz/def"));
747       std::cout << "    fs::relative(\"/abc/xyz/def\", \"/abc\") is "
748         << fs::relative("/abc/xyz/def", "/abc") << std::endl;
749       BOOST_TEST(fs::relative("abc\\xyz\\def", "abc") == path("xyz/def"));
750     }
751   }
752
753   //  query_and_decomposition_tests  ---------------------------------------------------//
754   //
755   //  remove_filename() is also tested here, because its specification depends on
756   //  a decomposition function.
757
758   void query_and_decomposition_tests()
759   {
760     std::cout << "query_and_decomposition_tests..." << std::endl;
761
762     // these are the examples given in reference docs, so check they work
763     BOOST_TEST(path("/foo/bar.txt").parent_path() == "/foo");
764     BOOST_TEST(path("/foo/bar").parent_path() == "/foo");
765     BOOST_TEST(path("/foo/bar/").parent_path() == "/foo/bar");
766     BOOST_TEST(path("/").parent_path() == "");
767     BOOST_TEST(path(".").parent_path() == "");
768     BOOST_TEST(path("..").parent_path() == "");
769     BOOST_TEST(path("/foo/bar.txt").filename() == "bar.txt");
770     BOOST_TEST(path("/foo/bar").filename() == "bar");
771     BOOST_TEST(path("/foo/bar/").filename() == ".");
772     BOOST_TEST(path("/").filename() == "/");
773     BOOST_TEST(path(".").filename() == ".");
774     BOOST_TEST(path("..").filename() == "..");
775
776     // stem() tests not otherwise covered
777     BOOST_TEST(path(".").stem() == ".");
778     BOOST_TEST(path("..").stem() == "..");
779     BOOST_TEST(path(".a").stem() == "");
780     BOOST_TEST(path("b").stem() == "b");
781     BOOST_TEST(path("a/b.txt").stem() == "b");
782     BOOST_TEST(path("a/b.").stem() == "b");
783     BOOST_TEST(path("a.b.c").stem() == "a.b");
784     BOOST_TEST(path("a.b.c.").stem() == "a.b.c");
785
786     // extension() tests not otherwise covered
787     BOOST_TEST(path(".").extension() == "");
788     BOOST_TEST(path("..").extension() == "");
789     BOOST_TEST(path(".a").extension() == ".a");
790     BOOST_TEST(path("a/b").extension() == "");
791     BOOST_TEST(path("a.b/c").extension() == "");
792     BOOST_TEST(path("a/b.txt").extension() == ".txt");
793     BOOST_TEST(path("a/b.").extension() == ".");
794     BOOST_TEST(path("a.b.c").extension() == ".c");
795     BOOST_TEST(path("a.b.c.").extension() == ".");
796     BOOST_TEST(path("a/").extension() == "");
797
798     // main q & d test sequence
799     path p;
800     path q;
801
802     p = q = "";
803     BOOST_TEST(p.relative_path().string() == "");
804     BOOST_TEST(p.parent_path().string() == "");
805     PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
806     BOOST_TEST(p.filename() == "");
807     BOOST_TEST(p.stem() == "");
808     BOOST_TEST(p.extension() == "");
809     BOOST_TEST(p.root_name() == "");
810     BOOST_TEST(p.root_directory() == "");
811     BOOST_TEST(p.root_path().string() == "");
812     BOOST_TEST(!p.has_root_path());
813     BOOST_TEST(!p.has_root_name());
814     BOOST_TEST(!p.has_root_directory());
815     BOOST_TEST(!p.has_relative_path());
816     BOOST_TEST(!p.has_filename());
817     BOOST_TEST(!p.has_stem());
818     BOOST_TEST(!p.has_extension());
819     BOOST_TEST(!p.has_parent_path());
820     BOOST_TEST(!p.is_absolute());
821
822     p = q = "/";
823     BOOST_TEST(p.relative_path().string() == "");
824     BOOST_TEST(p.parent_path().string() == "");
825     PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
826     BOOST_TEST(p.filename() == "/");
827     BOOST_TEST(p.stem() == "/");
828     BOOST_TEST(p.extension() == "");
829     BOOST_TEST(p.root_name() == "");
830     BOOST_TEST(p.root_directory() == "/");
831     BOOST_TEST(p.root_path().string() == "/");
832     BOOST_TEST(p.has_root_path());
833     BOOST_TEST(!p.has_root_name());
834     BOOST_TEST(p.has_root_directory());
835     BOOST_TEST(!p.has_relative_path());
836     BOOST_TEST(p.has_filename());
837     BOOST_TEST(p.has_stem());
838     BOOST_TEST(!p.has_extension());
839     BOOST_TEST(!p.has_parent_path());
840     if (platform == "POSIX")
841       BOOST_TEST(p.is_absolute());
842     else
843       BOOST_TEST(!p.is_absolute());
844
845     p = q = "//";
846     PATH_TEST_EQ(p.relative_path().string(), "");
847     PATH_TEST_EQ(p.parent_path().string(), "");
848     PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
849     PATH_TEST_EQ(p.filename(), "//");
850     PATH_TEST_EQ(p.stem(), "//");
851     PATH_TEST_EQ(p.extension(), "");
852     PATH_TEST_EQ(p.root_name(), "//");
853     PATH_TEST_EQ(p.root_directory(), "");
854     PATH_TEST_EQ(p.root_path().string(), "//");
855     BOOST_TEST(p.has_root_path());
856     BOOST_TEST(p.has_root_name());
857     BOOST_TEST(!p.has_root_directory());
858     BOOST_TEST(!p.has_relative_path());
859     BOOST_TEST(p.has_filename());
860     BOOST_TEST(p.has_stem());
861     BOOST_TEST(!p.has_extension());
862     BOOST_TEST(!p.has_parent_path());
863     BOOST_TEST(!p.is_absolute());
864
865     p = q = "///";
866     PATH_TEST_EQ(p.relative_path().string(), "");
867     PATH_TEST_EQ(p.parent_path().string(), "");
868     PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
869     PATH_TEST_EQ(p.filename(), "/");
870     PATH_TEST_EQ(p.stem(), "/");
871     PATH_TEST_EQ(p.extension(), "");
872     PATH_TEST_EQ(p.root_name(), "");
873     PATH_TEST_EQ(p.root_directory(), "/");
874     PATH_TEST_EQ(p.root_path().string(), "/");
875     BOOST_TEST(p.has_root_path());
876     BOOST_TEST(!p.has_root_name());
877     BOOST_TEST(p.has_root_directory());
878     BOOST_TEST(!p.has_relative_path());
879     BOOST_TEST(p.has_filename());
880     BOOST_TEST(p.has_stem());
881     BOOST_TEST(!p.has_extension());
882     BOOST_TEST(!p.has_parent_path());
883     if (platform == "POSIX")
884       BOOST_TEST(p.is_absolute());
885     else
886       BOOST_TEST(!p.is_absolute());
887
888     p = q = ".";
889     BOOST_TEST(p.relative_path().string() == ".");
890     BOOST_TEST(p.parent_path().string() == "");
891     PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
892     BOOST_TEST(p.filename() == ".");
893     BOOST_TEST(p.stem() == ".");
894     BOOST_TEST(p.extension() == "");
895     BOOST_TEST(p.root_name() == "");
896     BOOST_TEST(p.root_directory() == "");
897     BOOST_TEST(p.root_path().string() == "");
898     BOOST_TEST(!p.has_root_path());
899     BOOST_TEST(!p.has_root_name());
900     BOOST_TEST(!p.has_root_directory());
901     BOOST_TEST(p.has_relative_path());
902     BOOST_TEST(p.has_filename());
903     BOOST_TEST(p.has_stem());
904     BOOST_TEST(!p.has_extension());
905     BOOST_TEST(!p.has_parent_path());
906     BOOST_TEST(!p.is_absolute());
907
908     p = q = "..";
909     BOOST_TEST(p.relative_path().string() == "..");
910     BOOST_TEST(p.parent_path().string() == "");
911     PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
912     BOOST_TEST(p.filename() == "..");
913     BOOST_TEST(p.stem() == "..");
914     BOOST_TEST(p.extension() == "");
915     BOOST_TEST(p.root_name() == "");
916     BOOST_TEST(p.root_directory() == "");
917     BOOST_TEST(p.root_path().string() == "");
918     BOOST_TEST(!p.has_root_path());
919     BOOST_TEST(!p.has_root_name());
920     BOOST_TEST(!p.has_root_directory());
921     BOOST_TEST(p.has_relative_path());
922     BOOST_TEST(p.has_filename());
923     BOOST_TEST(p.has_stem());
924     BOOST_TEST(!p.has_extension());
925     BOOST_TEST(!p.has_parent_path());
926     BOOST_TEST(!p.is_absolute());
927
928     p = q = "foo";
929     BOOST_TEST(p.relative_path().string() == "foo");
930     BOOST_TEST(p.parent_path().string() == "");
931     PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
932     BOOST_TEST(p.filename() == "foo");
933     BOOST_TEST(p.stem() == "foo");
934     BOOST_TEST(p.extension() == "");
935     BOOST_TEST(p.root_name() == "");
936     BOOST_TEST(p.root_directory() == "");
937     BOOST_TEST(p.root_path().string() == "");
938     BOOST_TEST(!p.has_root_path());
939     BOOST_TEST(!p.has_root_name());
940     BOOST_TEST(!p.has_root_directory());
941     BOOST_TEST(p.has_relative_path());
942     BOOST_TEST(p.has_filename());
943     BOOST_TEST(p.has_stem());
944     BOOST_TEST(!p.has_extension());
945     BOOST_TEST(!p.has_parent_path());
946     BOOST_TEST(!p.is_absolute());
947
948     p = q = "/foo";
949     PATH_TEST_EQ(p.relative_path().string(), "foo");
950     PATH_TEST_EQ(p.parent_path().string(), "/");
951     PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
952     PATH_TEST_EQ(p.filename(), "foo");
953     PATH_TEST_EQ(p.stem(), "foo");
954     PATH_TEST_EQ(p.extension(), "");
955     PATH_TEST_EQ(p.root_name(), "");
956     PATH_TEST_EQ(p.root_directory(), "/");
957     PATH_TEST_EQ(p.root_path().string(), "/");
958     BOOST_TEST(p.has_root_path());
959     BOOST_TEST(!p.has_root_name());
960     BOOST_TEST(p.has_root_directory());
961     BOOST_TEST(p.has_relative_path());
962     BOOST_TEST(p.has_filename());
963     BOOST_TEST(p.has_stem());
964     BOOST_TEST(!p.has_extension());
965     BOOST_TEST(p.has_parent_path());
966     if (platform == "POSIX")
967       BOOST_TEST(p.is_absolute());
968     else
969       BOOST_TEST(!p.is_absolute());
970
971     p = q = "/foo/";
972     PATH_TEST_EQ(p.relative_path().string(), "foo/");
973     PATH_TEST_EQ(p.parent_path().string(), "/foo");
974     PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
975     PATH_TEST_EQ(p.filename(), ".");
976     PATH_TEST_EQ(p.stem(), ".");
977     PATH_TEST_EQ(p.extension(), "");
978     PATH_TEST_EQ(p.root_name(), "");
979     PATH_TEST_EQ(p.root_directory(), "/");
980     PATH_TEST_EQ(p.root_path().string(), "/");
981     BOOST_TEST(p.has_root_path());
982     BOOST_TEST(!p.has_root_name());
983     BOOST_TEST(p.has_root_directory());
984     BOOST_TEST(p.has_relative_path());
985     BOOST_TEST(p.has_filename());
986     BOOST_TEST(p.has_stem());
987     BOOST_TEST(!p.has_extension());
988     BOOST_TEST(p.has_parent_path());
989     if (platform == "POSIX")
990       BOOST_TEST(p.is_absolute());
991     else
992       BOOST_TEST(!p.is_absolute());
993
994     p = q = "///foo";
995     PATH_TEST_EQ(p.relative_path().string(), "foo");
996     PATH_TEST_EQ(p.parent_path().string(), "/");
997     PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
998     PATH_TEST_EQ(p.filename(), "foo");
999     PATH_TEST_EQ(p.root_name(), "");
1000     PATH_TEST_EQ(p.root_directory(), "/");
1001     PATH_TEST_EQ(p.root_path().string(), "/");
1002     BOOST_TEST(p.has_root_path());
1003     BOOST_TEST(!p.has_root_name());
1004     BOOST_TEST(p.has_root_directory());
1005     BOOST_TEST(p.has_relative_path());
1006     BOOST_TEST(p.has_filename());
1007     BOOST_TEST(p.has_parent_path());
1008     if (platform == "POSIX")
1009       BOOST_TEST(p.is_absolute());
1010     else
1011       BOOST_TEST(!p.is_absolute());
1012
1013     p = q = "foo/bar";
1014     BOOST_TEST(p.relative_path().string() == "foo/bar");
1015     BOOST_TEST(p.parent_path().string() == "foo");
1016     PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
1017     BOOST_TEST(p.filename() == "bar");
1018     BOOST_TEST(p.stem() == "bar");
1019     BOOST_TEST(p.extension() == "");
1020     BOOST_TEST(p.root_name() == "");
1021     BOOST_TEST(p.root_directory() == "");
1022     BOOST_TEST(p.root_path().string() == "");
1023     BOOST_TEST(!p.has_root_path());
1024     BOOST_TEST(!p.has_root_name());
1025     BOOST_TEST(!p.has_root_directory());
1026     BOOST_TEST(p.has_relative_path());
1027     BOOST_TEST(p.has_filename());
1028     BOOST_TEST(p.has_stem());
1029     BOOST_TEST(!p.has_extension());
1030     BOOST_TEST(p.has_parent_path());
1031     BOOST_TEST(!p.is_absolute());
1032
1033     p = q = "../foo";
1034     BOOST_TEST(p.relative_path().string() == "../foo");
1035     BOOST_TEST(p.parent_path().string() == "..");
1036     PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
1037     BOOST_TEST(p.filename() == "foo");
1038     BOOST_TEST(p.root_name() == "");
1039     BOOST_TEST(p.root_directory() == "");
1040     BOOST_TEST(p.root_path().string() == "");
1041     BOOST_TEST(!p.has_root_path());
1042     BOOST_TEST(!p.has_root_name());
1043     BOOST_TEST(!p.has_root_directory());
1044     BOOST_TEST(p.has_relative_path());
1045     BOOST_TEST(p.has_filename());
1046     BOOST_TEST(p.has_parent_path());
1047     BOOST_TEST(!p.is_absolute());
1048
1049     p = q = "..///foo";
1050     PATH_TEST_EQ(p.relative_path().string(), "..///foo");
1051     PATH_TEST_EQ(p.parent_path().string(), "..");
1052     PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
1053     PATH_TEST_EQ(p.filename(), "foo");
1054     PATH_TEST_EQ(p.root_name(), "");
1055     PATH_TEST_EQ(p.root_directory(), "");
1056     PATH_TEST_EQ(p.root_path().string(), "");
1057     BOOST_TEST(!p.has_root_path());
1058     BOOST_TEST(!p.has_root_name());
1059     BOOST_TEST(!p.has_root_directory());
1060     BOOST_TEST(p.has_relative_path());
1061     BOOST_TEST(p.has_filename());
1062     BOOST_TEST(p.has_parent_path());
1063     BOOST_TEST(!p.is_absolute());
1064
1065     p = q = "/foo/bar";
1066     BOOST_TEST(p.relative_path().string() == "foo/bar");
1067     BOOST_TEST(p.parent_path().string() == "/foo");
1068     PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
1069     BOOST_TEST(p.filename() == "bar");
1070     BOOST_TEST(p.root_name() == "");
1071     BOOST_TEST(p.root_directory() == "/");
1072     BOOST_TEST(p.root_path().string() == "/");
1073     BOOST_TEST(p.has_root_path());
1074     BOOST_TEST(!p.has_root_name());
1075     BOOST_TEST(p.has_root_directory());
1076     BOOST_TEST(p.has_relative_path());
1077     BOOST_TEST(p.has_filename());
1078     BOOST_TEST(p.has_parent_path());
1079     if (platform == "POSIX")
1080       BOOST_TEST(p.is_absolute());
1081     else
1082       BOOST_TEST(!p.is_absolute());
1083
1084     // Both POSIX and Windows allow two leading slashs
1085     // (POSIX meaning is implementation defined)
1086     PATH_TEST_EQ(path("//resource"), "//resource");
1087     PATH_TEST_EQ(path("//resource/"), "//resource/");
1088     PATH_TEST_EQ(path("//resource/foo"), "//resource/foo");
1089
1090     p = q = path("//net");
1091     PATH_TEST_EQ(p.string(), "//net");
1092     PATH_TEST_EQ(p.relative_path().string(), "");
1093     PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
1094     PATH_TEST_EQ(p.parent_path().string(), "");
1095     PATH_TEST_EQ(p.filename(), "//net");
1096     PATH_TEST_EQ(p.root_name(), "//net");
1097     PATH_TEST_EQ(p.root_directory(), "");
1098     PATH_TEST_EQ(p.root_path().string(), "//net");
1099     BOOST_TEST(p.has_root_path());
1100     BOOST_TEST(p.has_root_name());
1101     BOOST_TEST(!p.has_root_directory());
1102     BOOST_TEST(!p.has_relative_path());
1103     BOOST_TEST(p.has_filename());
1104     BOOST_TEST(!p.has_parent_path());
1105     BOOST_TEST(!p.is_absolute());
1106
1107     p = q = path("//net/");
1108     BOOST_TEST(p.relative_path().string() == "");
1109     BOOST_TEST(p.parent_path().string() == "//net");
1110     PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
1111     BOOST_TEST(p.filename() == "/");
1112     BOOST_TEST(p.root_name() == "//net");
1113     BOOST_TEST(p.root_directory() == "/");
1114     BOOST_TEST(p.root_path().string() == "//net/");
1115     BOOST_TEST(p.has_root_path());
1116     BOOST_TEST(p.has_root_name());
1117     BOOST_TEST(p.has_root_directory());
1118     BOOST_TEST(!p.has_relative_path());
1119     BOOST_TEST(p.has_filename());
1120     BOOST_TEST(p.has_parent_path());
1121     BOOST_TEST(p.is_absolute());
1122
1123     p = q = path("//net/foo");
1124     BOOST_TEST(p.relative_path().string() == "foo");
1125     BOOST_TEST(p.parent_path().string() == "//net/");
1126     PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
1127     BOOST_TEST(p.filename() == "foo");
1128     BOOST_TEST(p.root_name() == "//net");
1129     BOOST_TEST(p.root_directory() == "/");
1130     BOOST_TEST(p.root_path().string() == "//net/");
1131     BOOST_TEST(p.has_root_path());
1132     BOOST_TEST(p.has_root_name());
1133     BOOST_TEST(p.has_root_directory());
1134     BOOST_TEST(p.has_relative_path());
1135     BOOST_TEST(p.has_filename());
1136     BOOST_TEST(p.has_parent_path());
1137     BOOST_TEST(p.is_absolute());
1138
1139     p = q = path("//net///foo");
1140     PATH_TEST_EQ(p.relative_path().string(), "foo");
1141     PATH_TEST_EQ(p.parent_path().string(), "//net/");
1142     PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
1143     PATH_TEST_EQ(p.filename(), "foo");
1144     PATH_TEST_EQ(p.root_name(), "//net");
1145     PATH_TEST_EQ(p.root_directory(), "/");
1146     PATH_TEST_EQ(p.root_path().string(), "//net/");
1147     BOOST_TEST(p.has_root_path());
1148     BOOST_TEST(p.has_root_name());
1149     BOOST_TEST(p.has_root_directory());
1150     BOOST_TEST(p.has_relative_path());
1151     BOOST_TEST(p.has_filename());
1152     BOOST_TEST(p.has_parent_path());
1153     BOOST_TEST(p.is_absolute());
1154
1155     //  ticket 2739, infinite recursion leading to stack overflow, was caused
1156     //  by failure to handle this case correctly on Windows.
1157     p = path(":");
1158     PATH_TEST_EQ(p.parent_path().string(), "");
1159     PATH_TEST_EQ(p.filename(), ":");
1160     BOOST_TEST(!p.has_parent_path());
1161     BOOST_TEST(p.has_filename());
1162
1163     //  test some similar cases that both POSIX and Windows should handle identically
1164     p = path("c:");
1165     PATH_TEST_EQ(p.parent_path().string(), "");
1166     PATH_TEST_EQ(p.filename(), "c:");
1167     BOOST_TEST(!p.has_parent_path());
1168     BOOST_TEST(p.has_filename());
1169     p = path("cc:");
1170     PATH_TEST_EQ(p.parent_path().string(), "");
1171     PATH_TEST_EQ(p.filename(), "cc:");
1172     BOOST_TEST(!p.has_parent_path());
1173     BOOST_TEST(p.has_filename());
1174
1175     //  Windows specific tests
1176     if (platform == "Windows")
1177     {
1178
1179       //p = q = L"\\\\?\\";
1180       //BOOST_TEST(p.relative_path().string() == "");
1181       //BOOST_TEST(p.parent_path().string() == "");
1182       //PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
1183       //BOOST_TEST(p.filename() == "");
1184       //BOOST_TEST(p.stem() == "");
1185       //BOOST_TEST(p.extension() == "");
1186       //BOOST_TEST(p.root_name() == "");
1187       //BOOST_TEST(p.root_directory() == "");
1188       //BOOST_TEST(p.root_path().string() == "");
1189       //BOOST_TEST(!p.has_root_path());
1190       //BOOST_TEST(!p.has_root_name());
1191       //BOOST_TEST(!p.has_root_directory());
1192       //BOOST_TEST(!p.has_relative_path());
1193       //BOOST_TEST(!p.has_filename());
1194       //BOOST_TEST(!p.has_stem());
1195       //BOOST_TEST(!p.has_extension());
1196       //BOOST_TEST(!p.has_parent_path());
1197       //BOOST_TEST(!p.is_absolute());
1198
1199       p = q = path("c:");
1200       BOOST_TEST(p.relative_path().string() == "");
1201       BOOST_TEST(p.parent_path().string() == "");
1202       PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
1203       BOOST_TEST(p.filename() == "c:");
1204       BOOST_TEST(p.root_name() == "c:");
1205       BOOST_TEST(p.root_directory() == "");
1206       BOOST_TEST(p.root_path().string() == "c:");
1207       BOOST_TEST(p.has_root_path());
1208       BOOST_TEST(p.has_root_name());
1209       BOOST_TEST(!p.has_root_directory());
1210       BOOST_TEST(!p.has_relative_path());
1211       BOOST_TEST(p.has_filename());
1212       BOOST_TEST(!p.has_parent_path());
1213       BOOST_TEST(!p.is_absolute());
1214
1215       //p = q = path(L"\\\\?\\c:");
1216       //BOOST_TEST(p.relative_path().string() == "");
1217       //BOOST_TEST(p.parent_path().string() == "");
1218       //PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
1219       //BOOST_TEST(p.filename() == "c:");
1220       //BOOST_TEST(p.root_name() == "c:");
1221       //BOOST_TEST(p.root_directory() == "");
1222       //BOOST_TEST(p.root_path().string() == "c:");
1223       //BOOST_TEST(p.has_root_path());
1224       //BOOST_TEST(p.has_root_name());
1225       //BOOST_TEST(!p.has_root_directory());
1226       //BOOST_TEST(!p.has_relative_path());
1227       //BOOST_TEST(p.has_filename());
1228       //BOOST_TEST(!p.has_parent_path());
1229       //BOOST_TEST(!p.is_absolute());
1230
1231       p = q = path("c:foo");
1232       BOOST_TEST(p.relative_path().string() == "foo");
1233       BOOST_TEST(p.parent_path().string() == "c:");
1234       PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
1235       BOOST_TEST(p.filename() == "foo");
1236       BOOST_TEST(p.root_name() == "c:");
1237       BOOST_TEST(p.root_directory() == "");
1238       BOOST_TEST(p.root_path().string() == "c:");
1239       BOOST_TEST(p.has_root_path());
1240       BOOST_TEST(p.has_root_name());
1241       BOOST_TEST(!p.has_root_directory());
1242       BOOST_TEST(p.has_relative_path());
1243       BOOST_TEST(p.has_filename());
1244       BOOST_TEST(p.has_parent_path());
1245       BOOST_TEST(!p.is_absolute());
1246
1247       //p = q = path(L"\\\\?\\c:foo");
1248       //BOOST_TEST(p.relative_path().string() == "foo");
1249       //BOOST_TEST(p.parent_path().string() == "c:");
1250       //PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
1251       //BOOST_TEST(p.filename() == "foo");
1252       //BOOST_TEST(p.root_name() == "c:");
1253       //BOOST_TEST(p.root_directory() == "");
1254       //BOOST_TEST(p.root_path().string() == "c:");
1255       //BOOST_TEST(p.has_root_path());
1256       //BOOST_TEST(p.has_root_name());
1257       //BOOST_TEST(!p.has_root_directory());
1258       //BOOST_TEST(p.has_relative_path());
1259       //BOOST_TEST(p.has_filename());
1260       //BOOST_TEST(p.has_parent_path());
1261       //BOOST_TEST(!p.is_absolute());
1262
1263       p = q = path("c:/");
1264       BOOST_TEST(p.relative_path().string() == "");
1265       BOOST_TEST(p.parent_path().string() == "c:");
1266       PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
1267       BOOST_TEST(p.filename() == "/");
1268       BOOST_TEST(p.root_name() == "c:");
1269       BOOST_TEST(p.root_directory() == "/");
1270       BOOST_TEST(p.root_path().string() == "c:/");
1271       BOOST_TEST(p.has_root_path());
1272       BOOST_TEST(p.has_root_name());
1273       BOOST_TEST(p.has_root_directory());
1274       BOOST_TEST(!p.has_relative_path());
1275       BOOST_TEST(p.has_filename());
1276       BOOST_TEST(p.has_parent_path());
1277       BOOST_TEST(p.is_absolute());
1278
1279       p = q = path("c:..");
1280       BOOST_TEST(p.relative_path().string() == "..");
1281       BOOST_TEST(p.parent_path().string() == "c:");
1282       PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
1283       BOOST_TEST(p.filename() == "..");
1284       BOOST_TEST(p.root_name() == "c:");
1285       BOOST_TEST(p.root_directory() == "");
1286       BOOST_TEST(p.root_path().string() == "c:");
1287       BOOST_TEST(p.has_root_path());
1288       BOOST_TEST(p.has_root_name());
1289       BOOST_TEST(!p.has_root_directory());
1290       BOOST_TEST(p.has_relative_path());
1291       BOOST_TEST(p.has_filename());
1292       BOOST_TEST(p.has_parent_path());
1293       BOOST_TEST(!p.is_absolute());
1294
1295       p = q = path("c:/foo");
1296       PATH_TEST_EQ(p.relative_path().string(), "foo");
1297       PATH_TEST_EQ(p.parent_path().string(), "c:/");
1298       PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
1299       PATH_TEST_EQ(p.filename(), "foo");
1300       PATH_TEST_EQ(p.root_name(), "c:");
1301       PATH_TEST_EQ(p.root_directory(), "/");
1302       PATH_TEST_EQ(p.root_path().string(), "c:/");
1303       BOOST_TEST(p.has_root_path());
1304       BOOST_TEST(p.has_root_name());
1305       BOOST_TEST(p.has_root_directory());
1306       BOOST_TEST(p.has_relative_path());
1307       BOOST_TEST(p.has_filename());
1308       BOOST_TEST(p.has_parent_path());
1309       BOOST_TEST(p.is_absolute());
1310
1311       p = q = path("c://foo");
1312       PATH_TEST_EQ(p.relative_path().string(), "foo");
1313       PATH_TEST_EQ(p.parent_path().string(), "c:/");
1314       PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
1315       PATH_TEST_EQ(p.filename(), "foo");
1316       PATH_TEST_EQ(p.root_name(), "c:");
1317       PATH_TEST_EQ(p.root_directory(), "/");
1318       PATH_TEST_EQ(p.root_path().string(), "c:/");
1319       BOOST_TEST(p.has_root_path());
1320       BOOST_TEST(p.has_root_name());
1321       BOOST_TEST(p.has_root_directory());
1322       BOOST_TEST(p.has_relative_path());
1323       BOOST_TEST(p.has_filename());
1324       BOOST_TEST(p.has_parent_path());
1325       BOOST_TEST(p.is_absolute());
1326
1327       p = q = path("c:\\foo\\bar");
1328       PATH_TEST_EQ(p.relative_path().string(), "foo\\bar");
1329       PATH_TEST_EQ(p.parent_path().string(), "c:\\foo");
1330       PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
1331       PATH_TEST_EQ(p.filename(), "bar");
1332       PATH_TEST_EQ(p.root_name(), "c:");
1333       PATH_TEST_EQ(p.root_directory(), "\\");
1334       PATH_TEST_EQ(p.root_path().string(), "c:\\");
1335       BOOST_TEST(p.has_root_path());
1336       BOOST_TEST(p.has_root_name());
1337       BOOST_TEST(p.has_root_directory());
1338       BOOST_TEST(p.has_relative_path());
1339       BOOST_TEST(p.has_filename());
1340       BOOST_TEST(p.has_parent_path());
1341       BOOST_TEST(p.is_absolute());
1342
1343       p = q = path("prn:");
1344       BOOST_TEST(p.relative_path().string() == "");
1345       BOOST_TEST(p.parent_path().string() == "");
1346       PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
1347       BOOST_TEST(p.filename() == "prn:");
1348       BOOST_TEST(p.root_name() == "prn:");
1349       BOOST_TEST(p.root_directory() == "");
1350       BOOST_TEST(p.root_path().string() == "prn:");
1351       BOOST_TEST(p.has_root_path());
1352       BOOST_TEST(p.has_root_name());
1353       BOOST_TEST(!p.has_root_directory());
1354       BOOST_TEST(!p.has_relative_path());
1355       BOOST_TEST(p.has_filename());
1356       BOOST_TEST(!p.has_parent_path());
1357       BOOST_TEST(!p.is_absolute());
1358
1359       p = q = path("\\\\net\\\\\\foo");
1360       PATH_TEST_EQ(p.relative_path().string(), "foo");
1361       PATH_TEST_EQ(p.parent_path().string(), "\\\\net\\");
1362       PATH_TEST_EQ(q.remove_filename().string(), p.parent_path().string());
1363       PATH_TEST_EQ(p.filename(), "foo");
1364       PATH_TEST_EQ(p.root_name(), "\\\\net");
1365       PATH_TEST_EQ(p.root_directory(), "\\");
1366       PATH_TEST_EQ(p.root_path().string(), "\\\\net\\");
1367       BOOST_TEST(p.has_root_path());
1368       BOOST_TEST(p.has_root_name());
1369       BOOST_TEST(p.has_root_directory());
1370       BOOST_TEST(p.has_relative_path());
1371       BOOST_TEST(p.has_filename());
1372       BOOST_TEST(p.has_parent_path());
1373       BOOST_TEST(p.is_absolute());
1374     } // Windows
1375
1376     else
1377     { // POSIX
1378       PATH_TEST_EQ(path("/foo/bar/"), "/foo/bar/");
1379       PATH_TEST_EQ(path("//foo//bar//"), "//foo//bar//");
1380       PATH_TEST_EQ(path("///foo///bar///"), "///foo///bar///");
1381
1382       p = path("/usr/local/bin:/usr/bin:/bin");
1383       BOOST_TEST(p.string() == "/usr/local/bin:/usr/bin:/bin");
1384     } // POSIX
1385   }
1386
1387  //  composition_tests  ----------------------------------------------------------------//
1388
1389   void composition_tests()
1390   {
1391     std::cout << "composition_tests..." << std::endl;
1392
1393   }
1394
1395  //  construction_tests  ---------------------------------------------------------------//
1396
1397   void construction_tests()
1398   {
1399     std::cout << "construction_tests..." << std::endl;
1400
1401     PATH_TEST_EQ("", "");
1402
1403     PATH_TEST_EQ("foo", "foo");
1404     PATH_TEST_EQ("f", "f");
1405
1406     PATH_TEST_EQ("foo/", "foo/");
1407     PATH_TEST_EQ("f/", "f/");
1408     PATH_TEST_EQ("foo/..", "foo/..");
1409     PATH_TEST_EQ("foo/../", "foo/../");
1410     PATH_TEST_EQ("foo/bar/../..", "foo/bar/../..");
1411     PATH_TEST_EQ("foo/bar/../../", "foo/bar/../../");
1412     PATH_TEST_EQ("/", "/");
1413     PATH_TEST_EQ("/f", "/f");
1414
1415     PATH_TEST_EQ("/foo", "/foo");
1416     PATH_TEST_EQ("/foo/bar/", "/foo/bar/");
1417     PATH_TEST_EQ("//foo//bar//", "//foo//bar//");
1418     PATH_TEST_EQ("///foo///bar///", "///foo///bar///");
1419     PATH_TEST_EQ("\\/foo\\/bar\\/", "\\/foo\\/bar\\/");
1420     PATH_TEST_EQ("\\//foo\\//bar\\//", "\\//foo\\//bar\\//");
1421
1422     if (platform == "Windows")
1423     {
1424       PATH_TEST_EQ(path("c:") / "foo", "c:foo");
1425       PATH_TEST_EQ(path("c:") / "/foo", "c:/foo");
1426
1427       PATH_TEST_EQ("\\foo\\bar\\", "\\foo\\bar\\");
1428       PATH_TEST_EQ("\\\\foo\\\\bar\\\\", "\\\\foo\\\\bar\\\\");
1429       PATH_TEST_EQ("\\\\\\foo\\\\\\bar\\\\\\", "\\\\\\foo\\\\\\bar\\\\\\");
1430
1431       PATH_TEST_EQ("\\", "\\");
1432       PATH_TEST_EQ("\\f", "\\f");
1433       PATH_TEST_EQ("\\foo", "\\foo");
1434       PATH_TEST_EQ("foo\\bar", "foo\\bar");
1435       PATH_TEST_EQ("foo bar", "foo bar");
1436       PATH_TEST_EQ("c:", "c:");
1437       PATH_TEST_EQ("c:/", "c:/");
1438       PATH_TEST_EQ("c:.", "c:.");
1439       PATH_TEST_EQ("c:./foo", "c:./foo");
1440       PATH_TEST_EQ("c:.\\foo", "c:.\\foo");
1441       PATH_TEST_EQ("c:..", "c:..");
1442       PATH_TEST_EQ("c:/.", "c:/.");
1443       PATH_TEST_EQ("c:/..", "c:/..");
1444       PATH_TEST_EQ("c:/../", "c:/../");
1445       PATH_TEST_EQ("c:\\..\\", "c:\\..\\");
1446       PATH_TEST_EQ("c:/../..", "c:/../..");
1447       PATH_TEST_EQ("c:/../foo", "c:/../foo");
1448       PATH_TEST_EQ("c:\\..\\foo", "c:\\..\\foo");
1449       PATH_TEST_EQ("c:../foo", "c:../foo");
1450       PATH_TEST_EQ("c:..\\foo", "c:..\\foo");
1451       PATH_TEST_EQ("c:/../../foo", "c:/../../foo");
1452       PATH_TEST_EQ("c:\\..\\..\\foo", "c:\\..\\..\\foo");
1453       PATH_TEST_EQ("c:foo/..", "c:foo/..");
1454       PATH_TEST_EQ("c:/foo/..", "c:/foo/..");
1455       PATH_TEST_EQ("c:/..foo", "c:/..foo");
1456       PATH_TEST_EQ("c:foo", "c:foo");
1457       PATH_TEST_EQ("c:/foo", "c:/foo");
1458       PATH_TEST_EQ("\\\\netname", "\\\\netname");
1459       PATH_TEST_EQ("\\\\netname\\", "\\\\netname\\");
1460       PATH_TEST_EQ("\\\\netname\\foo", "\\\\netname\\foo");
1461       PATH_TEST_EQ("c:/foo", "c:/foo");
1462       PATH_TEST_EQ("prn:", "prn:");
1463     }
1464     else
1465     {
1466     }
1467
1468     PATH_TEST_EQ("foo/bar", "foo/bar");
1469     PATH_TEST_EQ("a/b", "a/b");  // probe for length effects
1470     PATH_TEST_EQ("..", "..");
1471     PATH_TEST_EQ("../..", "../..");
1472     PATH_TEST_EQ("/..", "/..");
1473     PATH_TEST_EQ("/../..", "/../..");
1474     PATH_TEST_EQ("../foo", "../foo");
1475     PATH_TEST_EQ("foo/..", "foo/..");
1476     PATH_TEST_EQ("foo/..bar", "foo/..bar");
1477     PATH_TEST_EQ("../f", "../f");
1478     PATH_TEST_EQ("/../f", "/../f");
1479     PATH_TEST_EQ("f/..", "f/..");
1480     PATH_TEST_EQ("foo/../..", "foo/../..");
1481     PATH_TEST_EQ("foo/../../..", "foo/../../..");
1482     PATH_TEST_EQ("foo/../bar", "foo/../bar");
1483     PATH_TEST_EQ("foo/bar/..", "foo/bar/..");
1484     PATH_TEST_EQ("foo/bar/../..", "foo/bar/../..");
1485     PATH_TEST_EQ("foo/bar/../blah", "foo/bar/../blah");
1486     PATH_TEST_EQ("f/../b", "f/../b");
1487     PATH_TEST_EQ("f/b/..", "f/b/..");
1488     PATH_TEST_EQ("f/b/../a", "f/b/../a");
1489     PATH_TEST_EQ("foo/bar/blah/../..", "foo/bar/blah/../..");
1490     PATH_TEST_EQ("foo/bar/blah/../../bletch", "foo/bar/blah/../../bletch");
1491     PATH_TEST_EQ("...", "...");
1492     PATH_TEST_EQ("....", "....");
1493     PATH_TEST_EQ("foo/...", "foo/...");
1494     PATH_TEST_EQ("abc.", "abc.");
1495     PATH_TEST_EQ("abc..", "abc..");
1496     PATH_TEST_EQ("foo/abc.", "foo/abc.");
1497     PATH_TEST_EQ("foo/abc..", "foo/abc..");
1498
1499     PATH_TEST_EQ(".abc", ".abc");
1500     PATH_TEST_EQ("a.c", "a.c");
1501     PATH_TEST_EQ("..abc", "..abc");
1502     PATH_TEST_EQ("a..c", "a..c");
1503     PATH_TEST_EQ("foo/.abc", "foo/.abc");
1504     PATH_TEST_EQ("foo/a.c", "foo/a.c");
1505     PATH_TEST_EQ("foo/..abc", "foo/..abc");
1506     PATH_TEST_EQ("foo/a..c", "foo/a..c");
1507
1508     PATH_TEST_EQ(".", ".");
1509     PATH_TEST_EQ("./foo", "./foo");
1510     PATH_TEST_EQ("./..", "./..");
1511     PATH_TEST_EQ("./../foo", "./../foo");
1512     PATH_TEST_EQ("foo/.", "foo/.");
1513     PATH_TEST_EQ("../.", "../.");
1514     PATH_TEST_EQ("./.", "./.");
1515     PATH_TEST_EQ("././.", "././.");
1516     PATH_TEST_EQ("./foo/.", "./foo/.");
1517     PATH_TEST_EQ("foo/./bar", "foo/./bar");
1518     PATH_TEST_EQ("foo/./.", "foo/./.");
1519     PATH_TEST_EQ("foo/./..", "foo/./..");
1520     PATH_TEST_EQ("foo/./../bar", "foo/./../bar");
1521     PATH_TEST_EQ("foo/../.", "foo/../.");
1522     PATH_TEST_EQ("././..", "././..");
1523     PATH_TEST_EQ("./../.", "./../.");
1524     PATH_TEST_EQ(".././.", ".././.");
1525   }
1526
1527   //  append_tests  --------------------------------------------------------------------//
1528
1529   void append_test_aux(const path & p, const std::string & s, const std::string & expect)
1530   {
1531     PATH_TEST_EQ((p / path(s)).string(), expect);
1532     PATH_TEST_EQ((p / s.c_str()).string(), expect);
1533     PATH_TEST_EQ((p / s).string(), expect);
1534     path x(p);
1535     x.append(s.begin(), s.end());
1536     PATH_TEST_EQ(x.string(), expect);
1537   }
1538
1539   void append_tests()
1540   {
1541     std::cout << "append_tests..." << std::endl;
1542
1543     // There are many control paths to be exercised, since empty paths and arguments,
1544     // paths with trailing separators, arguments with leading separators, with or without
1545     // other characters being present, are all separate cases that need to be tested.
1546     // Furthermore, some of the code to be tested is specific to argument categories,
1547     // so that results in further permutations to be tested.
1548
1549     //// code to generate test cases
1550     ////
1551     //// expected results must be checked by hand
1552     //// "foo\bar" expected result must be edited by hand and moved for Windows/POSIX
1553     ////
1554     //const char* x[]    = { "", "/", "foo", "foo/" };
1555     //const char* y[] = { "", "/", "bar", "/bar" };
1556
1557     //for (int i = 0; i < sizeof(x)/sizeof(char*); ++i)
1558     //  for (int j = 0; j < sizeof(y)/sizeof(char*); ++j)
1559     //  {
1560     //    std::cout << "\n    PATH_TEST_EQ(path(\"" << x[i] << "\") / \"" << y[j] << "\", \""
1561     //              << path(x[i]) / y[j] << "\");\n";
1562     //    std::cout << "    append_test_aux(\"" << x[i] << "\", \"" << y[j] << "\", \""
1563     //              << path(x[i]) / y[j] << "\");\n";
1564     //  }
1565
1566     PATH_TEST_EQ(path("") / "", "");
1567     append_test_aux("", "", "");
1568
1569     PATH_TEST_EQ(path("") / "/", "/");
1570     append_test_aux("", "/", "/");
1571
1572     PATH_TEST_EQ(path("") / "bar", "bar");
1573     append_test_aux("", "bar", "bar");
1574
1575     PATH_TEST_EQ(path("") / "/bar", "/bar");
1576     append_test_aux("", "/bar", "/bar");
1577
1578     PATH_TEST_EQ(path("/") / "", "/");
1579     append_test_aux("/", "", "/");
1580
1581     PATH_TEST_EQ(path("/") / "/", "//");
1582     append_test_aux("/", "/", "//");
1583
1584     PATH_TEST_EQ(path("/") / "bar", "/bar");
1585     append_test_aux("/", "bar", "/bar");
1586
1587     PATH_TEST_EQ(path("/") / "/bar", "//bar");
1588     append_test_aux("/", "/bar", "//bar");
1589
1590     PATH_TEST_EQ(path("foo") / "", "foo");
1591     append_test_aux("foo", "", "foo");
1592
1593     PATH_TEST_EQ(path("foo") / "/", "foo/");
1594     append_test_aux("foo", "/", "foo/");
1595
1596     PATH_TEST_EQ(path("foo") / "/bar", "foo/bar");
1597     append_test_aux("foo", "/bar", "foo/bar");
1598
1599     PATH_TEST_EQ(path("foo/") / "", "foo/");
1600     append_test_aux("foo/", "", "foo/");
1601
1602     PATH_TEST_EQ(path("foo/") / "/", "foo//");
1603     append_test_aux("foo/", "/", "foo//");
1604
1605     PATH_TEST_EQ(path("foo/") / "bar", "foo/bar");
1606     append_test_aux("foo/", "bar", "foo/bar");
1607
1608
1609     if (platform == "Windows")
1610     {
1611       PATH_TEST_EQ(path("foo") / "bar", "foo\\bar");
1612       append_test_aux("foo", "bar", "foo\\bar");
1613
1614       PATH_TEST_EQ(path("foo\\") / "\\bar", "foo\\\\bar");
1615       append_test_aux("foo\\", "\\bar", "foo\\\\bar");
1616
1617       // hand created test case specific to Windows
1618       PATH_TEST_EQ(path("c:") / "bar", "c:bar");
1619       append_test_aux("c:", "bar", "c:bar");
1620     }
1621     else
1622     {
1623       PATH_TEST_EQ(path("foo") / "bar", "foo/bar");
1624       append_test_aux("foo", "bar", "foo/bar");
1625     }
1626
1627     // ticket #6819
1628     union
1629     {
1630       char a[1];
1631       char b[3];
1632     } u;
1633
1634     u.b[0] = 'a';
1635     u.b[1] = 'b';
1636     u.b[2] = '\0';
1637
1638     path p6819;
1639     p6819 /= u.a;
1640     BOOST_TEST_EQ(p6819, path("ab"));
1641   }
1642
1643 //  self_assign_and_append_tests  ------------------------------------------------------//
1644
1645   void self_assign_and_append_tests()
1646   {
1647     std::cout << "self_assign_and_append_tests..." << std::endl;
1648
1649     path p;
1650
1651     p = "snafubar";
1652     PATH_TEST_EQ(p = p, "snafubar");
1653
1654     p = "snafubar";
1655     p = p.c_str();
1656     PATH_TEST_EQ(p, "snafubar");
1657
1658     p = "snafubar";
1659     p.assign(p.c_str(), path::codecvt());
1660     PATH_TEST_EQ(p, "snafubar");
1661
1662     p = "snafubar";
1663     PATH_TEST_EQ(p = p.c_str()+5, "bar");
1664
1665     p = "snafubar";
1666     PATH_TEST_EQ(p.assign(p.c_str() + 5, p.c_str() + 7), "ba");
1667
1668     p = "snafubar";
1669     p /= p;
1670     PATH_TEST_EQ(p, "snafubar" BOOST_DIR_SEP "snafubar");
1671
1672     p = "snafubar";
1673     p /= p.c_str();
1674     PATH_TEST_EQ(p, "snafubar" BOOST_DIR_SEP "snafubar");
1675
1676     p = "snafubar";
1677     p.append(p.c_str(), path::codecvt());
1678     PATH_TEST_EQ(p, "snafubar" BOOST_DIR_SEP "snafubar");
1679
1680     p = "snafubar";
1681     PATH_TEST_EQ(p.append(p.c_str() + 5, p.c_str() + 7), "snafubar" BOOST_DIR_SEP "ba");
1682   }
1683
1684
1685   //  name_function_tests  -------------------------------------------------------------//
1686
1687   void name_function_tests()
1688   {
1689     std::cout << "name_function_tests..." << std::endl;
1690
1691     BOOST_TEST(fs::portable_posix_name(std::string("x")));
1692     BOOST_TEST(fs::windows_name(std::string("x")));
1693     BOOST_TEST(fs::portable_name(std::string("x")));
1694     BOOST_TEST(fs::portable_directory_name(std::string("x")));
1695     BOOST_TEST(fs::portable_file_name(std::string("x")));
1696
1697     BOOST_TEST(fs::portable_posix_name(std::string(".")));
1698     BOOST_TEST(fs::windows_name(std::string(".")));
1699     BOOST_TEST(fs::portable_name(std::string(".")));
1700     BOOST_TEST(fs::portable_directory_name(std::string(".")));
1701     BOOST_TEST(!fs::portable_file_name(std::string(".")));
1702
1703     BOOST_TEST(fs::portable_posix_name(std::string("..")));
1704     BOOST_TEST(fs::windows_name(std::string("..")));
1705     BOOST_TEST(fs::portable_name(std::string("..")));
1706     BOOST_TEST(fs::portable_directory_name(std::string("..")));
1707     BOOST_TEST(!fs::portable_file_name(std::string("..")));
1708
1709     BOOST_TEST(!fs::native(std::string("")));
1710     BOOST_TEST(!fs::portable_posix_name(std::string("")));
1711     BOOST_TEST(!fs::windows_name(std::string("")));
1712     BOOST_TEST(!fs::portable_name(std::string("")));
1713     BOOST_TEST(!fs::portable_directory_name(std::string("")));
1714     BOOST_TEST(!fs::portable_file_name(std::string("")));
1715
1716     BOOST_TEST(!fs::native(std::string(" ")));
1717     BOOST_TEST(!fs::portable_posix_name(std::string(" ")));
1718     BOOST_TEST(!fs::windows_name(std::string(" ")));
1719     BOOST_TEST(!fs::portable_name(std::string(" ")));
1720     BOOST_TEST(!fs::portable_directory_name(std::string(" ")));
1721     BOOST_TEST(!fs::portable_file_name(std::string(" ")));
1722
1723     BOOST_TEST(!fs::portable_posix_name(std::string(":")));
1724     BOOST_TEST(!fs::windows_name(std::string(":")));
1725     BOOST_TEST(!fs::portable_name(std::string(":")));
1726     BOOST_TEST(!fs::portable_directory_name(std::string(":")));
1727     BOOST_TEST(!fs::portable_file_name(std::string(":")));
1728
1729     BOOST_TEST(fs::portable_posix_name(std::string("-")));
1730     BOOST_TEST(fs::windows_name(std::string("-")));
1731     BOOST_TEST(!fs::portable_name(std::string("-")));
1732     BOOST_TEST(!fs::portable_directory_name(std::string("-")));
1733     BOOST_TEST(!fs::portable_file_name(std::string("-")));
1734
1735     BOOST_TEST(!fs::portable_posix_name(std::string("foo bar")));
1736     BOOST_TEST(fs::windows_name(std::string("foo bar")));
1737     BOOST_TEST(!fs::windows_name(std::string(" bar")));
1738     BOOST_TEST(!fs::windows_name(std::string("foo ")));
1739     BOOST_TEST(!fs::portable_name(std::string("foo bar")));
1740     BOOST_TEST(!fs::portable_directory_name(std::string("foo bar")));
1741     BOOST_TEST(!fs::portable_file_name(std::string("foo bar")));
1742
1743     BOOST_TEST(fs::portable_posix_name(std::string("foo.bar")));
1744     BOOST_TEST(fs::windows_name(std::string("foo.bar")));
1745     BOOST_TEST(fs::portable_name(std::string("foo.bar")));
1746     BOOST_TEST(!fs::portable_directory_name(std::string("foo.bar")));
1747     BOOST_TEST(fs::portable_file_name(std::string("foo.bar")));
1748
1749     BOOST_TEST(fs::portable_posix_name(std::string("foo.barf")));
1750     BOOST_TEST(fs::windows_name(std::string("foo.barf")));
1751     BOOST_TEST(fs::portable_name(std::string("foo.barf")));
1752     BOOST_TEST(!fs::portable_directory_name(std::string("foo.barf")));
1753     BOOST_TEST(!fs::portable_file_name(std::string("foo.barf")));
1754
1755     BOOST_TEST(fs::portable_posix_name(std::string(".foo")));
1756     BOOST_TEST(fs::windows_name(std::string(".foo")));
1757     BOOST_TEST(!fs::portable_name(std::string(".foo")));
1758     BOOST_TEST(!fs::portable_directory_name(std::string(".foo")));
1759     BOOST_TEST(!fs::portable_file_name(std::string(".foo")));
1760
1761     BOOST_TEST(fs::portable_posix_name(std::string("foo.")));
1762     BOOST_TEST(!fs::windows_name(std::string("foo.")));
1763     BOOST_TEST(!fs::portable_name(std::string("foo.")));
1764     BOOST_TEST(!fs::portable_directory_name(std::string("foo.")));
1765     BOOST_TEST(!fs::portable_file_name(std::string("foo.")));
1766   }
1767
1768   //  replace_extension_tests  ---------------------------------------------------------//
1769
1770   void replace_extension_tests()
1771   {
1772     std::cout << "replace_extension_tests..." << std::endl;
1773
1774     BOOST_TEST(path().replace_extension().empty());
1775     BOOST_TEST(path().replace_extension("a") == ".a");
1776     BOOST_TEST(path().replace_extension("a.") == ".a.");
1777     BOOST_TEST(path().replace_extension(".a") == ".a");
1778     BOOST_TEST(path().replace_extension("a.txt") == ".a.txt");
1779     // see the rationale in html docs for explanation why this works:
1780     BOOST_TEST(path().replace_extension(".txt") == ".txt");
1781
1782     BOOST_TEST(path("a.txt").replace_extension() == "a");
1783     BOOST_TEST(path("a.txt").replace_extension("") == "a");
1784     BOOST_TEST(path("a.txt").replace_extension(".") == "a.");
1785     BOOST_TEST(path("a.txt").replace_extension(".tex") == "a.tex");
1786     BOOST_TEST(path("a.txt").replace_extension("tex") == "a.tex");
1787     BOOST_TEST(path("a.").replace_extension(".tex") == "a.tex");
1788     BOOST_TEST(path("a.").replace_extension("tex") == "a.tex");
1789     BOOST_TEST(path("a").replace_extension(".txt") == "a.txt");
1790     BOOST_TEST(path("a").replace_extension("txt") == "a.txt");
1791     BOOST_TEST(path("a.b.txt").replace_extension(".tex") == "a.b.tex");
1792     BOOST_TEST(path("a.b.txt").replace_extension("tex") == "a.b.tex");
1793     BOOST_TEST(path("a/b").replace_extension(".c") == "a/b.c");
1794     PATH_TEST_EQ(path("a.txt/b").replace_extension(".c"), "a.txt/b.c"); // ticket 4702
1795     BOOST_TEST(path("foo.txt").replace_extension("exe") == "foo.exe");  // ticket 5118
1796     BOOST_TEST(path("foo.txt").replace_extension(".tar.bz2")
1797                                                     == "foo.tar.bz2");  // ticket 5118
1798   }
1799
1800   //  make_preferred_tests  ------------------------------------------------------------//
1801
1802   void make_preferred_tests()
1803   {
1804     std::cout << "make_preferred_tests..." << std::endl;
1805
1806     if (platform == "Windows")
1807     {
1808       BOOST_TEST(path("//abc\\def/ghi").make_preferred().native()
1809         == path("\\\\abc\\def\\ghi").native());
1810     }
1811     else
1812     {
1813       BOOST_TEST(path("//abc\\def/ghi").make_preferred().native()
1814         == path("//abc\\def/ghi").native());
1815     }
1816   }
1817
1818   //  lexically_normal_tests  ----------------------------------------------------------//
1819
1820   void lexically_normal_tests()
1821   {
1822     std::cout << "lexically_normal_tests..." << std::endl;
1823
1824     //  Note: lexically_lexically_normal() uses /= to build up some results, so these results will
1825     //  have the platform's preferred separator. Since that is immaterial to the correct
1826     //  functioning of lexically_lexically_normal(), the test results are converted to generic form,
1827     //  and the expected results are also given in generic form. Otherwise many of the
1828     //  tests would incorrectly be reported as failing on Windows.
1829
1830     PATH_TEST_EQ(path("").lexically_normal().generic_path(), "");
1831     PATH_TEST_EQ(path("/").lexically_normal().generic_path(), "/");
1832     PATH_TEST_EQ(path("//").lexically_normal().generic_path(), "//");
1833     PATH_TEST_EQ(path("///").lexically_normal().generic_path(), "/");
1834     PATH_TEST_EQ(path("f").lexically_normal().generic_path(), "f");
1835     PATH_TEST_EQ(path("foo").lexically_normal().generic_path(), "foo");
1836     PATH_TEST_EQ(path("foo/").lexically_normal().generic_path(), "foo/.");
1837     PATH_TEST_EQ(path("f/").lexically_normal().generic_path(), "f/.");
1838     PATH_TEST_EQ(path("/foo").lexically_normal().generic_path(), "/foo");
1839     PATH_TEST_EQ(path("foo/bar").lexically_normal().generic_path(), "foo/bar");
1840     PATH_TEST_EQ(path("..").lexically_normal().generic_path(), "..");
1841     PATH_TEST_EQ(path("../..").lexically_normal().generic_path(), "../..");
1842     PATH_TEST_EQ(path("/..").lexically_normal().generic_path(), "/..");
1843     PATH_TEST_EQ(path("/../..").lexically_normal().generic_path(), "/../..");
1844     PATH_TEST_EQ(path("../foo").lexically_normal().generic_path(), "../foo");
1845     PATH_TEST_EQ(path("foo/..").lexically_normal().generic_path(), ".");
1846     PATH_TEST_EQ(path("foo/../").lexically_normal().generic_path(), "./.");
1847     PATH_TEST_EQ((path("foo") / "..").lexically_normal().generic_path() , ".");
1848     PATH_TEST_EQ(path("foo/...").lexically_normal().generic_path(), "foo/...");
1849     PATH_TEST_EQ(path("foo/.../").lexically_normal().generic_path(), "foo/.../.");
1850     PATH_TEST_EQ(path("foo/..bar").lexically_normal().generic_path(), "foo/..bar");
1851     PATH_TEST_EQ(path("../f").lexically_normal().generic_path(), "../f");
1852     PATH_TEST_EQ(path("/../f").lexically_normal().generic_path(), "/../f");
1853     PATH_TEST_EQ(path("f/..").lexically_normal().generic_path(), ".");
1854     PATH_TEST_EQ((path("f") / "..").lexically_normal().generic_path() , ".");
1855     PATH_TEST_EQ(path("foo/../..").lexically_normal().generic_path(), "..");
1856     PATH_TEST_EQ(path("foo/../../").lexically_normal().generic_path(), "../.");
1857     PATH_TEST_EQ(path("foo/../../..").lexically_normal().generic_path(), "../..");
1858     PATH_TEST_EQ(path("foo/../../../").lexically_normal().generic_path(), "../../.");
1859     PATH_TEST_EQ(path("foo/../bar").lexically_normal().generic_path(), "bar");
1860     PATH_TEST_EQ(path("foo/../bar/").lexically_normal().generic_path(), "bar/.");
1861     PATH_TEST_EQ(path("foo/bar/..").lexically_normal().generic_path(), "foo");
1862     PATH_TEST_EQ(path("foo/./bar/..").lexically_normal().generic_path(), "foo");
1863     std::cout << path("foo/./bar/..").lexically_normal() << std::endl;  // outputs "foo"
1864     PATH_TEST_EQ(path("foo/bar/../").lexically_normal().generic_path(), "foo/.");
1865     PATH_TEST_EQ(path("foo/./bar/../").lexically_normal().generic_path(), "foo/.");
1866     std::cout << path("foo/./bar/../").lexically_normal() << std::endl;  // POSIX: "foo/.", Windows: "foo\."
1867     PATH_TEST_EQ(path("foo/bar/../..").lexically_normal().generic_path(), ".");
1868     PATH_TEST_EQ(path("foo/bar/../../").lexically_normal().generic_path(), "./.");
1869     PATH_TEST_EQ(path("foo/bar/../blah").lexically_normal().generic_path(), "foo/blah");
1870     PATH_TEST_EQ(path("f/../b").lexically_normal().generic_path(), "b");
1871     PATH_TEST_EQ(path("f/b/..").lexically_normal().generic_path(), "f");
1872     PATH_TEST_EQ(path("f/b/../").lexically_normal().generic_path(), "f/.");
1873     PATH_TEST_EQ(path("f/b/../a").lexically_normal().generic_path(), "f/a");
1874     PATH_TEST_EQ(path("foo/bar/blah/../..").lexically_normal().generic_path(), "foo");
1875     PATH_TEST_EQ(path("foo/bar/blah/../../bletch").lexically_normal().generic_path(), "foo/bletch");
1876     PATH_TEST_EQ(path("//net").lexically_normal().generic_path(), "//net");
1877     PATH_TEST_EQ(path("//net/").lexically_normal().generic_path(), "//net/");
1878     PATH_TEST_EQ(path("//..net").lexically_normal().generic_path(), "//..net");
1879     PATH_TEST_EQ(path("//net/..").lexically_normal().generic_path(), "//net/..");
1880     PATH_TEST_EQ(path("//net/foo").lexically_normal().generic_path(), "//net/foo");
1881     PATH_TEST_EQ(path("//net/foo/").lexically_normal().generic_path(), "//net/foo/.");
1882     PATH_TEST_EQ(path("//net/foo/..").lexically_normal().generic_path(), "//net/");
1883     PATH_TEST_EQ(path("//net/foo/../").lexically_normal().generic_path(), "//net/.");
1884
1885     PATH_TEST_EQ(path("/net/foo/bar").lexically_normal().generic_path(), "/net/foo/bar");
1886     PATH_TEST_EQ(path("/net/foo/bar/").lexically_normal().generic_path(), "/net/foo/bar/.");
1887     PATH_TEST_EQ(path("/net/foo/..").lexically_normal().generic_path(), "/net");
1888     PATH_TEST_EQ(path("/net/foo/../").lexically_normal().generic_path(), "/net/.");
1889
1890     PATH_TEST_EQ(path("//net//foo//bar").lexically_normal().generic_path(), "//net/foo/bar");
1891     PATH_TEST_EQ(path("//net//foo//bar//").lexically_normal().generic_path(), "//net/foo/bar/.");
1892     PATH_TEST_EQ(path("//net//foo//..").lexically_normal().generic_path(), "//net/");
1893     PATH_TEST_EQ(path("//net//foo//..//").lexically_normal().generic_path(), "//net/.");
1894
1895     PATH_TEST_EQ(path("///net///foo///bar").lexically_normal().generic_path(), "/net/foo/bar");
1896     PATH_TEST_EQ(path("///net///foo///bar///").lexically_normal().generic_path(), "/net/foo/bar/.");
1897     PATH_TEST_EQ(path("///net///foo///..").lexically_normal().generic_path(), "/net");
1898     PATH_TEST_EQ(path("///net///foo///..///").lexically_normal().generic_path(), "/net/.");
1899
1900     if (platform == "Windows")
1901     {
1902       PATH_TEST_EQ(path("c:..").lexically_normal().generic_path(), "c:..");
1903       PATH_TEST_EQ(path("c:foo/..").lexically_normal().generic_path(), "c:");
1904
1905       PATH_TEST_EQ(path("c:foo/../").lexically_normal().generic_path(), "c:.");
1906
1907       PATH_TEST_EQ(path("c:/foo/..").lexically_normal().generic_path(), "c:/");
1908       PATH_TEST_EQ(path("c:/foo/../").lexically_normal().generic_path(), "c:/.");
1909       PATH_TEST_EQ(path("c:/..").lexically_normal().generic_path(), "c:/..");
1910       PATH_TEST_EQ(path("c:/../").lexically_normal().generic_path(), "c:/../.");
1911       PATH_TEST_EQ(path("c:/../..").lexically_normal().generic_path(), "c:/../..");
1912       PATH_TEST_EQ(path("c:/../../").lexically_normal().generic_path(), "c:/../../.");
1913       PATH_TEST_EQ(path("c:/../foo").lexically_normal().generic_path(), "c:/../foo");
1914       PATH_TEST_EQ(path("c:/../foo/").lexically_normal().generic_path(), "c:/../foo/.");
1915       PATH_TEST_EQ(path("c:/../../foo").lexically_normal().generic_path(), "c:/../../foo");
1916       PATH_TEST_EQ(path("c:/../../foo/").lexically_normal().generic_path(), "c:/../../foo/.");
1917       PATH_TEST_EQ(path("c:/..foo").lexically_normal().generic_path(), "c:/..foo");
1918     }
1919     else // POSIX
1920     {
1921       PATH_TEST_EQ(path("c:..").lexically_normal(), "c:..");
1922       PATH_TEST_EQ(path("c:foo/..").lexically_normal(), ".");
1923       PATH_TEST_EQ(path("c:foo/../").lexically_normal(), "./.");
1924       PATH_TEST_EQ(path("c:/foo/..").lexically_normal(), "c:");
1925       PATH_TEST_EQ(path("c:/foo/../").lexically_normal(), "c:/.");
1926       PATH_TEST_EQ(path("c:/..").lexically_normal(), ".");
1927       PATH_TEST_EQ(path("c:/../").lexically_normal(), "./.");
1928       PATH_TEST_EQ(path("c:/../..").lexically_normal(), "..");
1929       PATH_TEST_EQ(path("c:/../../").lexically_normal(), "../.");
1930       PATH_TEST_EQ(path("c:/../foo").lexically_normal(), "foo");
1931       PATH_TEST_EQ(path("c:/../foo/").lexically_normal(), "foo/.");
1932       PATH_TEST_EQ(path("c:/../../foo").lexically_normal(), "../foo");
1933       PATH_TEST_EQ(path("c:/../../foo/").lexically_normal(), "../foo/.");
1934       PATH_TEST_EQ(path("c:/..foo").lexically_normal(), "c:/..foo");
1935     }
1936   }
1937
1938   inline void odr_use(const path::value_type& c)
1939   {
1940     static const path::value_type dummy = '\0';
1941     BOOST_TEST(&c != &dummy);
1942   }
1943
1944 } // unnamed namespace
1945
1946 static boost::filesystem::path ticket_6737 = "FilePath";  // #6737 reported this crashed
1947                                                           // on VC++ debug mode build
1948 const boost::filesystem::path ticket_6690("test");  // #6690 another V++ static init crash
1949
1950 //--------------------------------------------------------------------------------------//
1951 //                                                                                      //
1952 //                                     main                                             //
1953 //                                                                                      //
1954 //--------------------------------------------------------------------------------------//
1955
1956 int cpp_main(int, char*[])
1957 {
1958   // The choice of platform is make at runtime rather than compile-time
1959   // so that compile errors for all platforms will be detected even though
1960   // only the current platform is runtime tested.
1961   platform = (platform == "Win32" || platform == "Win64" || platform == "Cygwin")
1962                ? "Windows"
1963                : "POSIX";
1964   std::cout << "Platform is " << platform << '\n';
1965
1966   BOOST_TEST(p1.string() != p3.string());
1967   p3 = p2;
1968   BOOST_TEST(p1.string() == p3.string());
1969
1970   path p04("foobar");
1971   BOOST_TEST(p04.string() == "foobar");
1972   p04 = p04; // self-assignment
1973   BOOST_TEST(p04.string() == "foobar");
1974
1975   construction_tests();
1976   append_tests();
1977   self_assign_and_append_tests();
1978   overload_tests();
1979   query_and_decomposition_tests();
1980   composition_tests();
1981   iterator_tests();
1982   non_member_tests();
1983   exception_tests();
1984   name_function_tests();
1985   replace_extension_tests();
1986   make_preferred_tests();
1987   lexically_normal_tests();
1988
1989   // verify deprecated names still available
1990
1991 # ifndef BOOST_FILESYSTEM_NO_DEPRECATED
1992
1993   p1.branch_path();
1994   p1.leaf();
1995   path p_remove_leaf;
1996   p_remove_leaf.remove_leaf();
1997
1998 # endif
1999
2000   std::string s1("//:somestring");  // this used to be treated specially
2001
2002   // check the path member templates
2003   p5.assign(s1.begin(), s1.end());
2004
2005   PATH_TEST_EQ(p5.string(), "//:somestring");
2006   p5 = s1;
2007   PATH_TEST_EQ(p5.string(), "//:somestring");
2008
2009   // this code, courtesy of David Whetstone, detects a now fixed bug that
2010   // derefereced the end iterator (assuming debug build with checked itors)
2011   std::vector<char> v1;
2012   p5.assign(v1.begin(), v1.end());
2013   std::string s2(v1.begin(), v1.end());
2014   PATH_TEST_EQ(p5.string(), s2);
2015   p5.assign(s1.begin(), s1.begin() + 1);
2016   PATH_TEST_EQ(p5.string(), "/");
2017
2018   BOOST_TEST(p1 != p4);
2019   BOOST_TEST(p1.string() == p2.string());
2020   BOOST_TEST(p1.string() == p3.string());
2021   BOOST_TEST(path("foo").filename() == "foo");
2022   BOOST_TEST(path("foo").parent_path().string() == "");
2023   BOOST_TEST(p1.filename() == "fum");
2024   BOOST_TEST(p1.parent_path().string() == "fe/fi/fo");
2025   BOOST_TEST(path("").empty() == true);
2026   BOOST_TEST(path("foo").empty() == false);
2027
2028   // inserter and extractor tests
2029 # if !defined(BOOST_MSVC) || BOOST_MSVC > 1300 // bypass VC++ 7.0 and earlier
2030   std::cout << "\nInserter and extractor test...";
2031   std::stringstream ss;
2032   ss << fs::path("foo/bar") << std::endl;
2033   fs::path round_trip;
2034   ss >> round_trip;
2035   BOOST_TEST(round_trip.string() == "foo/bar");
2036   std::cout << round_trip.string() << "..." << round_trip << " complete\n";
2037 # endif
2038
2039   // Check that path constants have definitions
2040   // https://svn.boost.org/trac10/ticket/12759
2041   odr_use(path::separator);
2042   odr_use(path::preferred_separator);
2043   odr_use(path::dot);
2044
2045   return ::boost::report_errors();
2046 }