relative_proposal.html 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510
  1. <html>
  2. <head>
  3. <meta http-equiv="Content-Language" content="en-us">
  4. <meta name="GENERATOR" content="Microsoft FrontPage 5.0">
  5. <meta name="ProgId" content="FrontPage.Editor.Document">
  6. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  7. <title>Filesystem Relative Proposal</title>
  8. <link href="styles.css" rel="stylesheet">
  9. </head>
  10. <body>
  11. <table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111">
  12. <tr>
  13. <td width="277">
  14. <a href="../../../index.htm">
  15. <img src="../../../boost.png" alt="boost.png (6897 bytes)" align="middle" width="300" height="86" border="0"></a></td>
  16. <td align="middle">
  17. <font size="7">Filesystem Relative<br>
  18. Draft Proposal</font>
  19. </td>
  20. </tr>
  21. </table>
  22. <table border="0" cellpadding="5" cellspacing="0" style="border-collapse: collapse"
  23. bordercolor="#111111" bgcolor="#D7EEFF" width="100%">
  24. <tr>
  25. <td><a href="index.htm">Home</a> &nbsp;&nbsp;
  26. <a href="tutorial.html">Tutorial</a> &nbsp;&nbsp;
  27. <a href="reference.html">Reference</a> &nbsp;&nbsp;
  28. <a href="faq.htm">FAQ</a> &nbsp;&nbsp;
  29. <a href="release_history.html">Releases</a> &nbsp;&nbsp;
  30. <a href="portability_guide.htm">Portability</a> &nbsp;&nbsp;
  31. <a href="v3.html">V3 Intro</a> &nbsp;&nbsp;
  32. <a href="v3_design.html">V3 Design</a> &nbsp;&nbsp;
  33. <a href="deprecated.html">Deprecated</a> &nbsp;&nbsp;
  34. <a href="issue_reporting.html">Bug Reports </a>&nbsp;&nbsp;
  35. </td>
  36. </table>
  37. <p><a href="#Introduction">
  38. Introduction</a><br>
  39. &nbsp;&nbsp;&nbsp; <a href="#Acknowledgement">Acknowledgement</a><br>
  40. &nbsp;&nbsp; &nbsp;<a href="#Preliminary-implementation">Preliminary implementation</a><br>
  41. <a href="#Requirements">Requirements</a><br>
  42. <a href="#Issues">Issues</a><br>
  43. <a href="#Design-decisions">
  44. Design decisions</a><br>
  45. &nbsp;&nbsp;&nbsp;&nbsp;<a href="#Provide-separate-relative">Provide separate lexical and
  46. operational <code>relative</code> functions</a><br>
  47. &nbsp;&nbsp;&nbsp; <a href="#Provide-separate-proximate">Provide
  48. separate lexical and operational <code>proximate</code> functions</a><br>
  49. &nbsp;&nbsp;&nbsp; <a href="#Add-lexical-functions">Add lexical functions as <code>path</code> member functions</a><br>
  50. &nbsp;&nbsp;&nbsp;&nbsp;<a href="#Provide-normal">Provide a non-member function
  51. <code>lexically_normal</code> returning a
  52. normal form path</a><br>
  53. &nbsp;&nbsp;&nbsp;&nbsp;<a href="#Provide-weakly">Provide a <code>weakly_canonical</code> operational function</a><br>
  54. &nbsp;&nbsp;&nbsp;&nbsp;<a href="#just-work">Resolve issues in ways that &quot;just work&quot; for users</a><br>
  55. &nbsp;&nbsp;&nbsp;&nbsp;<a href="#mismatch">Specify <code>lexical relative</code> in terms
  56. of <code>std::mismatch</code></a><br>
  57. &nbsp;&nbsp;&nbsp;&nbsp;<a href="#Specify-op-rel-weakly">Specify operational <code>relative</code> in terms of <code>
  58. weakly_canonical</code></a><br>
  59. &nbsp;&nbsp;&nbsp;&nbsp;<a href="#Specify-op-rel-lex-rel">Specify operational <code>relative</code> in terms of
  60. <code>lexically
  61. relative</code></a><br>
  62. <a href="#Proposed-wording">Proposed wording</a><br>
  63. &nbsp;&nbsp;&nbsp; <a href="#Define-normal-form">Define <i>normal form</i></a><br>
  64. &nbsp;&nbsp;&nbsp; <a href="#New-class-path-member-functions">New class path member functions</a><br>
  65. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="#Synopsis-path">Synopsis</a><br>
  66. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="#Specification-path">Specification</a><br>
  67. &nbsp;&nbsp;&nbsp; <a href="#operational-functions">New operational functions</a><br>
  68. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="#Synopsis-ops">Synopsis</a><br>
  69. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="#Specification-ops">Specification</a></p>
  70. <h2>
  71. <a name="Introduction">Introduction</a></h2>
  72. <p>There have been requests for a Filesystem library relative function for at
  73. least ten years.</p>
  74. <p>
  75. The requested functionality seems simple - given two paths with a common
  76. prefix, return the non-common suffix portion of one of the paths such that
  77. it is relative to the other path.</p>
  78. <p>
  79. In terms of the Filesystem library,</p>
  80. <blockquote>
  81. <pre>path p(&quot;/a/b/c&quot;);
  82. path base(&quot;/a/b&quot;);
  83. path rel = relative(p, base); // the requested function
  84. cout &lt;&lt; rel &lt;&lt; endl; // outputs &quot;c&quot;
  85. assert(absolute(rel, base) == p);</pre>
  86. </blockquote>
  87. <p>If that was all there was to it, the Filesystem library would have had a
  88. <code>relative</code> function years ago.</p>
  89. <blockquote>
  90. <p>Blocking issues: Clashing requirements, symlinks, directory placeholders (<i>dot</i>,
  91. <i>dot-dot</i>), user-expectations, corner cases.</p>
  92. </blockquote>
  93. <h3><a name="Acknowledgement">Acknowledgement</a></h3>
  94. <p>A paper by Jamie Allsop, <i>Additions to Filesystem supporting Relative Paths</i>,
  95. is what broke my mental logjam. Much of what follows is based directly on
  96. Jamie&#39;s analysis and proposal. The <code>weakly_canonical</code> function and
  97. aspects of the semantic specifications are my contributions. Mistakes, of
  98. course, are mine.</p>
  99. <h3><a name="Preliminary-implementation">Preliminary implementation</a></h3>
  100. <p>A preliminary implementation is available in the
  101. <a href="https://github.com/boostorg/filesystem/tree/feature/relative2">
  102. feature/relative2</a> branch of the Boost Filesystem Git repository. See
  103. <a href="https://github.com/boostorg/filesystem/tree/feature/relative2">
  104. github.com/boostorg/filesystem/tree/feature/relative2</a></p>
  105. <h2><a name="Requirements">Requirements</a></h2>
  106. <b><a name="Requirement-1">Requirement 1</a>:</b> Some uses require symlinks be followed; i.e. the path must be resolved in
  107. the actual file system.<p><b><a name="Requirement-2">Requirement 2</a>: </b>Some uses require symlinks not be followed; i.e. the path must not be
  108. resolved in the actual file system.</p>
  109. <b><a name="Requirement-3">Requirement 3</a>: </b>Some uses require removing redundant current directory (<i>dot</i>)
  110. or parent directory (<i>dot-dot</i>) placeholders.<p><b>
  111. <a name="Requirement-4">Requirement 4</a>: </b>Some uses do not require removing redundant current directory (<i>dot</i>)
  112. or parent directory (<i>dot-dot</i>) placeholders since the path is known to
  113. be
  114. already in normal form.</p>
  115. <h2><a name="Issues">Issues</a></h2>
  116. <p><b><a name="Issue-1">Issue 1</a>:</b> What happens if <code>p</code>
  117. and <code>base</code> are themselves relative?</p>
  118. <b><a name="Issue-2">Issue 2</a>:</b> What happens if there is no common prefix? Is this an error, the whole of
  119. <code>p</code> is relative to <code>base</code>, or something else?<p><b>
  120. <a name="Issue-3">Issue 3</a>:</b> What happens if <code>p</code>, <code>base</code>, or both are empty?</p>
  121. <b><a name="Issue-4">Issue 4</a>:</b> What happens if <code>p</code> and <code>base</code> are the same?<p>
  122. <b><a name="Issue-5">Issue 5</a>:</b> How is the &quot;common prefix&quot; determined?</p>
  123. <b><a name="Issue-6">Issue 6</a>:</b> What happens if portions of <code>p</code> or <code>base</code> exist but
  124. the entire path does not exist and yet symlinks need to be followed?<p><b>
  125. <a name="Issue-7">Issue 7</a>:</b> What happens when a symlink in the existing portion of a path is affected
  126. by a directory (<i>dot-dot</i>) placeholder in a later non-existent portion of
  127. the path?</p>
  128. <p><b><a name="Issue-8">Issue 8</a>:</b> Overly complex semantics (and thus
  129. specifications) in preliminary designs made reasoning about uses difficult.</p>
  130. <p><b><a name="Issue-9">Issue 9</a>: </b>Some uses never have redundant current directory (<i>dot</i>)
  131. or parent directory (<i>dot-dot</i>) placeholders, so a removal operation
  132. would be an unnecessary expense although otherwise harmless.</p>
  133. <h2>
  134. <a name="Design-decisions">Design decisions</a></h2>
  135. <h4>
  136. <a name="Provide-separate-relative">Provide separate</a> lexical and
  137. operational <code>relative</code> functions</h4>
  138. <p align="left">
  139. Resolves the conflict between <a href="#Requirement-1">requirement 1</a>
  140. and <a href="#Requirement-2">requirement 2</a> and ensures both
  141. requirements are met.</p>
  142. <p>
  143. A purely lexical function is needed by users working with directory
  144. hierarchies that do not actually exist.</p>
  145. <p>
  146. An operational function that queries the current file system for existence
  147. and follows symlinks is needed by users working with actual existing
  148. directory hierarchies.</p>
  149. <h4>
  150. <a name="Provide-separate-proximate">Provide separate</a> lexical and operational
  151. <code>proximate</code> functions</h4>
  152. <p>
  153. Although not the only possibility, a likely fallback when the relative
  154. functions cannot find a relative path is to return the path being made relative. As
  155. a convenience, the <code>proximate</code> functions do just that.</p>
  156. <h4>
  157. <a name="Add-lexical-functions">Add lexical functions as
  158. <code>path</code> member functions</a></h4>
  159. <p dir="ltr">
  160. The Filesystem library is unusual in that it has several functions with
  161. both lexical (i.e. cheap) and operational (i.e. expensive due to file
  162. system access) forms with differing semantics. It is important that users
  163. choose the form that meets their application&#39;s specific needs. The library
  164. has always made the distinction via the convention of lexical functions
  165. being members of class <code>path</code>, while operational functions are
  166. non-member functions. The lexical functions proposed here also use the
  167. name prefix <code>lexically_</code> to drive home the distinction.</p>
  168. <p>
  169. For the contrary argument, see Sutter and Alexandrescu, <i>C++ Coding Standards</i>, 44:
  170. &quot;Prefer writing nonmember nonfriend functions&quot;, and Meyers, <i>Effective C++ Third Edition</i>, 23:
  171. &quot;Prefer non-member non-friend functions to member functions.&quot;</p>
  172. <h4>
  173. <a name="Provide-normal">Provide</a><b> </b>a non-member function <code>
  174. <a href="#normal">lexically_normal</a></code> returning a
  175. <a href="#normal-form">normal form</a> path</h4>
  176. <p>
  177. Enables resolution of <a href="#Requirement-3">requirement 3</a> and
  178. <a href="#Requirement-4">requirement 4</a> in a way consistent with
  179. <a href="#Issue-9">issue 9</a>. Is a contributor to the resolution of
  180. <a href="#Issue-8">issue 8</a>.</p>
  181. <p>
  182. &quot;Normalization&quot; is the process of removing redundant current directory (<i>dot</i>)
  183. , parent
  184. directory (<i>dot-dot</i>), and directory separator elements.</p>
  185. <p>
  186. Normalization is a byproduct the current <code>canonical</code> function.
  187. But for the path returned by the
  188. proposed <code><a href="#weakly_canonical">weakly_canonical</a></code> function,
  189. only any leading canonic portion is in canonical form. So any trailing
  190. portion of the returned path has not been normalized.</p>
  191. <p>
  192. Jamie Allsop has proposed adding a separate normalization function returning a
  193. path, and I agree with him.</p>
  194. <p>
  195. Boost.filesystem has a deprecated non-const normalization function that
  196. modifies the path, but I agree with Jamie that a function returning a path
  197. is a better solution.</p>
  198. <h4>
  199. <a name="Provide-weakly">Provide</a><b> </b>a <code><a href="#weakly_canonical">weakly_canonical</a></code> operational function</h4>
  200. <p>
  201. Resolves <a href="#Issue-6">issue 6</a>, <a href="#Issue-7">issue 7</a>,
  202. <a href="#Issue-9">issue 9</a>, and is a contributor to the resolution of
  203. <a href="#Issue-8">issue 8</a>.</p>
  204. <p>
  205. The operational function
  206. <code>weakly_canonical(p)</code> returns a path composed of <code>
  207. canonical(x)/y</code>, where <code>x</code> is a path composed of the
  208. longest leading sequence of elements in <code>p</code> that exist, and
  209. <code>y</code> is a path composed of the remaining trailing non-existent elements of
  210. <code>p</code> if any. &quot;<code>weakly</code>&quot; refers to weakened existence
  211. requirements compared to the existing canonical function.</p>
  212. <ul>
  213. <li>Having <code>weakly_canonical</code> as a separate function, and then
  214. specifying the processing of operational <code>relative</code> arguments in
  215. terms of calls to <code>weakly_canonical</code> makes it much easier to
  216. specify the operational <code>relative</code> function and reason about it.
  217. The difficulty of reasoning about operational <code>relative</code>
  218. semantics before the invention of <code>weakly_canonical</code> was what led to its
  219. initial development.</li>
  220. <li>Having <code>weakly_canonical</code> as a separate function also allows
  221. use in other contexts.</li>
  222. <li>Specifying the return be in <a href="#normal-form">normal form</a> is an
  223. engineering trade-off to resolve <a href="#Issue-7">issue 7</a> in a way that
  224. just works for most use cases.</li>
  225. <li>Specifying normative encouragement to not perform unneeded normalization
  226. is a reasonable resolution for <a href="#Issue-9">issue 9</a>.</li>
  227. </ul>
  228. <h4>
  229. Resolve issues in ways that &quot;<a name="just-work">just work</a>&quot; for users</h4>
  230. <p>
  231. Resolves issues <a href="#Issue-1">1</a>, <a href="#Issue-2">2</a>,
  232. <a href="#Issue-3">3</a>, <a href="#Issue-4">4</a>, <a href="#Issue-7">6</a>,
  233. and <a href="#Issue-7">7</a>. Is a contributor to the resolution of
  234. <a href="#Issue-8">issue 8</a>.</p>
  235. <p>
  236. The &quot;just works&quot; approach was suggested by Jamie Allsop. It is implemented
  237. by specifying a reasonable return value for all of the &quot;What happens
  238. if...&quot; corner case issues, rather that treating them as hard errors
  239. requiring an exception or error code.</p>
  240. <h4>
  241. Specify <a href="#lex-proximate"><code>lexically relative</code></a> in terms
  242. of <code>std::<a name="mismatch">mismatch</a></code></h4>
  243. <p>
  244. Resolves <a href="#Issue-5">issue 5</a>. Is a contributor to the
  245. resolution of <a href="#Issue-8">issue 8</a>.</p>
  246. <h4>
  247. <a name="Specify-op-rel-weakly">Specify</a> <a href="#op-proximate">operational <code>relative</code></a> in terms of <code>
  248. <a href="#weakly_canonical">weakly_canonical</a></code></h4>
  249. <p>
  250. Is a contributor to the resolution of <a href="#Issue-8">issue 8</a>.</p>
  251. <ul>
  252. <li>Covers a wide range of uses cases since a single function works for
  253. existing, non-existing, and partially existing paths.</li>
  254. <li>Works correctly for partially existing paths that contain symlinks.</li>
  255. </ul>
  256. <h4>
  257. <a name="Specify-op-rel-lex-rel">Specify</a> <a href="#op-proximate">operational <code>relative</code></a> in terms of
  258. <a href="#lex-proximate"><code>lexically
  259. relative</code></a></h4>
  260. <p>
  261. Is a contributor to the resolution of <a href="#Issue-5">issue 5</a> and
  262. <a href="#Issue-8">issue 8</a>.</p>
  263. <p>
  264. If would be confusing to users and difficult to specify correctly if the
  265. two functions had differing semantics:</p>
  266. <ul>
  267. <li>When either or both paths are empty.</li>
  268. <li>When all elements of the two paths match exactly.</li>
  269. <li>Because different matching algorithms were used.</li>
  270. <li>Because although the same matching algorithm was used, it was applied in different ways.</li>
  271. </ul>
  272. <p>
  273. These problems are avoided by specifying operational <code>relative</code>
  274. in terms of lexical <code>relative</code> after preparatory
  275. calls to operational functions.</p>
  276. <h2><a name="Proposed-wording">Proposed wording</a></h2>
  277. <p><span style="background-color: #DBDBDB"><i>&quot;Overview:&quot; sections below are
  278. non-normative experiments attempting to make the normative reference
  279. specifications easier to grasp.</i></span></p>
  280. <h3><a name="Define-normal-form">Define <i>normal form</i></a></h3>
  281. <p>A path is in <b><i><a name="normal-form">normal form</a></i></b> if it has no
  282. redundant current directory (<i>dot</i>) or parent directory (<i>dot-dot</i>)
  283. elements. The normal form for an empty path is an empty path. The normal form
  284. for a path ending in a <i>directory-separator</i> that is not the root directory
  285. is the same path with a current directory (<i>dot</i>) element appended.</p>
  286. <p><span style="background-color: #DBDBDB"><i>The last sentence above is not
  287. necessary for POSIX-like or Windows-like operating systems, but supports systems
  288. like OpenVMS that use different syntax for directory and regular-file names.</i></span></p>
  289. <h3><a name="New-class-path-member-functions">New class path member functions</a></h3>
  290. <h4><a name="Synopsis-path">Synopsis</a></h4>
  291. <pre>path lexically_normal() const;
  292. path lexically_relative(const path&amp; base) const;
  293. path lexically_proximate(const path&amp; base) const;</pre>
  294. <h4><a name="Specification-path">Specification</a></h4>
  295. <pre>path <a name="lex-normal">lexically_normal</a>() const;</pre>
  296. <blockquote>
  297. <p><i>Overview:</i> Returns <code>*this</code> with redundant current directory
  298. (<i>dot</i>), parent directory (<i>dot-dot</i>), and <i>directory-separator</i> elements removed.</p>
  299. <p><i>Returns:</i> <code>*this</code> in <a href="#normal-form">normal form</a>.</p>
  300. <p><i>Remarks:</i> Uses <code>operator/=</code> to compose the returned path.</p>
  301. <p>[<i>Example:</i></p>
  302. <p><code>assert(path(&quot;foo/./bar/..&quot;).lexically_normal() == &quot;foo&quot;);<br>
  303. assert(path(&quot;foo/.///bar/../&quot;).lexically_normal() == &quot;foo/.&quot;);</code></p>
  304. <p>The above assertions will succeed.<i> </i>On Windows, the
  305. returned path&#39;s <i>directory-separator</i> characters will be backslashes rather than slashes, but that
  306. does not affect <code>path</code> equality.<i> —end example</i>]</p>
  307. </blockquote>
  308. <pre>path <a name="lex-relative">lexically_relative</a>(const path&amp; base) const;</pre>
  309. <blockquote>
  310. <p><i>Overview:</i> Returns <code>*this</code> made relative to <code>base</code>.
  311. Treats empty or identical paths as corner cases, not errors. Does not resolve
  312. symlinks. Does not first normalize <code>*this</code> or <code>base</code>.</p>
  313. <p><i>Remarks:</i> Uses <code>std::mismatch(begin(), end(), base.begin(), base.end())</code>, to determine the first mismatched element of
  314. <code>*this</code> and <code>base</code>. Uses <code>operator==</code> to
  315. determine if elements match. </p>
  316. <p><i>Returns:</i> </p>
  317. <ul>
  318. <li>
  319. <code>path()</code> if the first mismatched element of <code>*this</code> is equal to <code>
  320. begin()</code> or the first mismatched element
  321. of <code>base</code> is equal to <code>base.begin()</code>, or<br>&nbsp;
  322. </li>
  323. <li>
  324. <code>path(&quot;.&quot;)</code> if the first mismatched element of <code>
  325. *this</code> is equal to <code>
  326. end()</code> and the first mismatched element
  327. of <code>base</code> is equal to <code>base.end()</code>, or<br>&nbsp;
  328. </li>
  329. <li>An object of class <code>path</code> composed via application of <code>
  330. operator/= path(&quot;..&quot;)</code> for each element in the half-open
  331. range [first
  332. mismatched element of <code>base</code>, <code>base.end()</code>), and then
  333. application of <code>operator/=</code> for each element in the half-open
  334. range
  335. [first mismatched element of <code>*this</code>, <code>end()</code>).
  336. </li>
  337. </ul>
  338. <p>[<i>Example:</i></p>
  339. <p><code>assert(path(&quot;/a/d&quot;).lexically_relative(&quot;/a/b/c&quot;) == &quot;../../d&quot;);<br>
  340. assert(path(&quot;/a/b/c&quot;).lexically_relative(&quot;/a/d&quot;) == &quot;../b/c&quot;);<br>
  341. assert(path(&quot;a/b/c&quot;).lexically_relative(&quot;a&quot;) == &quot;b/c&quot;);<br>
  342. assert(path(&quot;a/b/c&quot;).lexically_relative(&quot;a/b/c/x/y&quot;) == &quot;../..&quot;);<br>
  343. assert(path(&quot;a/b/c&quot;).lexically_relative(&quot;a/b/c&quot;) == &quot;.&quot;);<br>
  344. assert(path(&quot;a/b&quot;).lexically_relative(&quot;c/d&quot;) == &quot;&quot;);</code></p>
  345. <p>The above assertions will succeed.<i> </i>On Windows, the
  346. returned path&#39;s <i>directory-separator</i>s will be backslashes rather than
  347. forward slashes, but that
  348. does not affect <code>path</code> equality.<i> —end example</i>]</p>
  349. <p>[<i>Note:</i> If symlink following semantics are desired, use the operational function <code>
  350. <a href="#op-proximate">relative</a></code>&nbsp; <i>—end note</i>]</p>
  351. <p>[<i>Note:</i> If <a href="#normal">normalization</a> is needed to ensure
  352. consistent matching of elements, apply <code><a href="#normal">lexically_normal()</a></code>
  353. to <code>*this</code>, <code>base</code>, or both. <i>—end note</i>]</p>
  354. </blockquote>
  355. <pre>path <a name="lex-proximate">lexically_proximate</a>(const path&amp; base) const;</pre>
  356. <blockquote>
  357. <p><i>Returns:</i> If the value of <code>lexically_relative(base)</code> is
  358. not an empty path, return it. Otherwise return <code>*this</code>.</p>
  359. <p>[<i>Note:</i> If symlink following semantics are desired, use the operational function
  360. <code><a href="#op-proximate">proximate</a></code>&nbsp; <i>—end note</i>]</p>
  361. <p>[<i>Note:</i> If <a href="#normal">normalization</a> is needed to ensure
  362. consistent matching of elements, apply <code><a href="#normal">lexically_normal()</a></code>
  363. to <code>*this</code>, <code>base</code>, or both. <i>—end note</i>]</p>
  364. </blockquote>
  365. <h3>New <a name="operational-functions">operational functions</a></h3>
  366. <h4><a name="Synopsis-ops">Synopsis</a></h4>
  367. <pre>path weakly_canonical(const path&amp; p);
  368. path weakly_canonical(const path&amp; p, system::error_code&amp; ec);
  369. path relative(const path&amp; p, system::error_code&amp; ec);
  370. path relative(const path&amp; p, const path&amp; base=current_path());
  371. path relative(const path&amp; p, const path&amp; base, system::error_code&amp; ec);
  372. path proximate(const path&amp; p, system::error_code&amp; ec);
  373. path proximate(const path&amp; p, const path&amp; base=current_path());
  374. path proximate(const path&amp; p, const path&amp; base, system::error_code&amp; ec);
  375. </pre>
  376. <h4><a name="Specification-ops">Specification</a></h4>
  377. <pre>path <a name="weakly_canonical">weakly_canonical</a>(const path&amp; p);
  378. path weakly_canonical(const path&amp; p, system::error_code&amp; ec);</pre>
  379. <blockquote>
  380. <i>Overview:</i> Returns <code>p</code> with symlinks resolved and the result
  381. normalized.<p>
  382. <i>Returns: </i>
  383. A path composed of the result of calling the <code>canonical</code> function on
  384. a path composed of the leading elements of <code>p</code> that exist, if any,
  385. followed by the elements of <code>p</code> that do not exist, if any.</p>
  386. <p><i>Postcondition:</i> The returned path is in <a href="#normal">normal form</a>.</p>
  387. <p><i>Remarks:</i> Uses <code>operator/=</code> to compose the returned path.
  388. Uses the <code>status</code> function to determine existence.</p>
  389. <p><i>Remarks:</i> Implementations are encouraged to avoid unnecessary
  390. normalization such as when <code>canonical</code> has already been called on the
  391. entirety of <code>p</code>.</p>
  392. <p><i>Throws:</i>&nbsp; As specified in Error reporting.</p>
  393. </blockquote>
  394. <pre>path <a name="op-relative">relative</a>(const path&amp; p, system::error_code&amp; ec);</pre>
  395. <blockquote>
  396. <p><i>Returns:</i> <code>relative(p, current_path(), ec)</code>.</p>
  397. <p><i>Throws:</i>&nbsp; As specified in Error reporting.</p>
  398. </blockquote>
  399. <pre>path relative(const path&amp; p, const path&amp; base=current_path());
  400. path relative(const path&amp; p, const path&amp; base, system::error_code&amp; ec);</pre>
  401. <blockquote>
  402. <p><i>Overview:</i> Returns <code>p</code> made relative to <code>
  403. base</code>. Treats empty or identical paths as corner cases, not errors.
  404. Resolves symlinks and normalizes both <code>p</code> and <code>base</code>
  405. before other processing.</p>
  406. <p><i>Returns:</i> <code><a href="#weakly_canonical">weakly_canonical</a>(p).l<a href="#lex-proximate">exically_relative</a>(<a href="#weakly_canonical">weakly_canonical</a>(base))</code>. The second form returns <code>path()</code> if an error occurs.</p>
  407. <p><i>Throws:</i> As specified in Error reporting.</p>
  408. </blockquote>
  409. <pre>path <a name="op-proximate">proximate</a>(const path&amp; p, system::error_code&amp; ec);</pre>
  410. <blockquote>
  411. <p><i>Returns:</i> <code>proximate(p, current_path(), ec)</code>.</p>
  412. <p><i>Throws:</i>&nbsp; As specified in Error reporting.</p>
  413. </blockquote>
  414. <pre>path proximate(const path&amp; p, const path&amp; base=current_path());
  415. path proximate(const path&amp; p, const path&amp; base, system::error_code&amp; ec);</pre>
  416. <blockquote>
  417. <p><i>Returns:</i> <code><a href="#weakly_canonical">weakly_canonical</a>(p).l<a href="#lex-proximate">exically_proximate</a>(<a href="#weakly_canonical">weakly_canonical</a>(base))</code>. The second form returns <code>path()</code> if an error occurs.</p>
  418. <p><i>Throws:</i> As specified in Error reporting.</p>
  419. </blockquote>
  420. <hr>
  421. <p>&copy; Copyright Beman Dawes 2015</p>
  422. <p>Distributed under the Boost Software License, Version 1.0. See
  423. <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a></p>
  424. <p>Revised
  425. <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan -->25 October 2015<!--webbot bot="Timestamp" endspan i-checksum="32445" --></p>
  426. </body>
  427. </html>