Skip to content

Commit

Permalink
Removed deprecated APIs.
Browse files Browse the repository at this point in the history
Removed APIs that were marked as deprecated a long time ago. Disabled
by default support for path construction, assignment and appending from
container types. Users can still enable this functionality by defining
BOOST_FILESYSTEM_DEPRECATED.

Updated docs, tests and examples accordingly.
  • Loading branch information
Lastique committed Jan 14, 2024
1 parent c0b3b7f commit 5df060e
Show file tree
Hide file tree
Showing 16 changed files with 19 additions and 978 deletions.
341 changes: 1 addition & 340 deletions doc/deprecated.html
Original file line number Diff line number Diff line change
Expand Up @@ -63,162 +63,6 @@ <h2><a name="Deprecated-names">Deprecated names</a> and features</h2>
<td style="font-size: 10pt" valign="top">
<p style="font-size: 10pt"><b><i>New name</i></b></td>
</tr>
<tr>
<td style="font-size: 10pt" valign="top"><code>class path</code></td>
<td style="font-size: 10pt" valign="top"><code>branch_path()</code></td>
<td style="font-size: 10pt" valign="top">&#10004;</td>
<td style="font-size: 10pt" valign="top"><code>parent_path()</code></td>
</tr>
<tr>
<td style="font-size: 10pt" valign="top">
<code>class path</code></td>
<td style="font-size: 10pt" valign="top">
<code>canonize()</code></td>
<td style="font-size: 10pt" valign="top">
&nbsp;</td>
<td style="font-size: 10pt" valign="top">
<i>Function removed</i></td>
</tr>
<tr>
<td style="font-size: 10pt" valign="top">
<code>class path</code></td>
<td style="font-size: 10pt" valign="top">
<code>default_name_check()</code></td>
<td style="font-size: 10pt" valign="top">
&#10004;</td>
<td style="font-size: 10pt" valign="top">
<i>Function removed</i></td>
</tr>
<tr>
<td style="font-size: 10pt" valign="top">
<code>class path</code></td>
<td style="font-size: 10pt" valign="top">
<code>default_name_check(name_check)</code></td>
<td style="font-size: 10pt" valign="top">
&#10004;</td>
<td style="font-size: 10pt" valign="top">
<i>Function removed</i></td>
</tr>
<tr>
<td style="font-size: 10pt" valign="top">
<code>class path</code></td>
<td style="font-size: 10pt" valign="top">
<code>default_name_check_writable()</code></td>
<td style="font-size: 10pt" valign="top">
&#10004;</td>
<td style="font-size: 10pt" valign="top">
<i>Function removed</i></td>
</tr>
<tr>
<td style="font-size: 10pt" valign="top"><code>class path</code></td>
<td style="font-size: 10pt" valign="top"><code>directory_string()</code></td>
<td style="font-size: 10pt" valign="top">&#10004;</td>
<td style="font-size: 10pt" valign="top"><code>string</code></td>
</tr>
<tr>
<td style="font-size: 10pt" valign="top"><code>class path</code></td>
<td style="font-size: 10pt" valign="top"><code>external_directory_string()</code></td>
<td style="font-size: 10pt" valign="top">&#10004;</td>
<td style="font-size: 10pt" valign="top"><code>native()</code></td>
</tr>
<tr>
<td style="font-size: 10pt" valign="top"><code>class path</code></td>
<td style="font-size: 10pt" valign="top"><code>external_file_string()</code></td>
<td style="font-size: 10pt" valign="top">&#10004;</td>
<td style="font-size: 10pt" valign="top"><code>native()</code></td>
</tr>
<tr>
<td style="font-size: 10pt" valign="top"><code>class path</code></td>
<td style="font-size: 10pt" valign="top"><code>file_string()</code></td>
<td style="font-size: 10pt" valign="top">&#10004;</td>
<td style="font-size: 10pt" valign="top"><code>string()</code></td>
</tr>
<tr>
<td style="font-size: 10pt" valign="top"><code>class path</code></td>
<td style="font-size: 10pt" valign="top"><code>has_branch_path()</code></td>
<td style="font-size: 10pt" valign="top">&#10004;</td>
<td style="font-size: 10pt" valign="top"><code>has_parent_path()</code></td>
</tr>
<tr>
<td style="font-size: 10pt" valign="top"><code>class path</code></td>
<td style="font-size: 10pt" valign="top"><code>has_leaf()</code></td>
<td style="font-size: 10pt" valign="top">&#10004;</td>
<td style="font-size: 10pt" valign="top"><code>has_filename()</code></td>
</tr>
<tr>
<td style="font-size: 10pt" valign="top"><code>class path</code></td>
<td style="font-size: 10pt" valign="top"><code>is_complete()</code></td>
<td style="font-size: 10pt" valign="top">&#10004;</td>
<td style="font-size: 10pt" valign="top"><code>is_absolute()</code></td>
</tr>
<tr>
<td style="font-size: 10pt" valign="top"><code>class path</code></td>
<td style="font-size: 10pt" valign="top"><code>leaf()</code></td>
<td style="font-size: 10pt" valign="top">&#10004;</td>
<td style="font-size: 10pt" valign="top"><code>filename()</code></td>
</tr>
<tr>
<td style="font-size: 10pt" valign="top">
<code>class path</code></td>
<td style="font-size: 10pt" valign="top">
<code>native_directory_string()</code></td>
<td style="font-size: 10pt" valign="top">
&#10004;</td>
<td style="font-size: 10pt" valign="top">
<code>string()</code></td>
</tr>
<tr>
<td style="font-size: 10pt" valign="top">
<code>class path</code></td>
<td style="font-size: 10pt" valign="top">
<code>native_file_string()</code></td>
<td style="font-size: 10pt" valign="top">
&#10004;</td>
<td style="font-size: 10pt" valign="top">
<code>string()</code></td>
</tr>
<tr>
<td style="font-size: 10pt" valign="top">
<code>class path</code></td>
<td style="font-size: 10pt" valign="top">
<code>normalize()</code></td>
<td style="font-size: 10pt" valign="top">
&#10004;</td>
<td style="font-size: 10pt" valign="top">
<i>Function removed</i></td>
</tr>
<tr>
<td style="font-size: 10pt" valign="top">
<code>class path</code></td>
<td style="font-size: 10pt" valign="top">
<code>path(const string_type&amp; str, name_check)</code></td>
<td style="font-size: 10pt" valign="top">
&#10004;</td>
<td style="font-size: 10pt" valign="top">
<i>Function removed. Workaround ignores </i><code>name_check</code><i>
argument.</i></td>
</tr>
<tr>
<td style="font-size: 10pt" valign="top">
<code>class path</code></td>
<td style="font-size: 10pt" valign="top">
<code>path(const string_type::value_type* s,&nbsp; name_check)</code></td>
<td style="font-size: 10pt" valign="top">
&#10004;</td>
<td style="font-size: 10pt" valign="top">
<i>Function removed. Workaround ignores </i><code>name_check</code><i>
argument.</i></td>
</tr>
<tr>
<td style="font-size: 10pt" valign="top">
<code>class path</code></td>
<td style="font-size: 10pt" valign="top">
<p style="font-size: 10pt"><code>remove_leaf()</code></td>
<td style="font-size: 10pt" valign="top">
&#10004;</td>
<td style="font-size: 10pt" valign="top">
<p style="font-size: 10pt"><code>remove_filename()</code></td>
</tr>
<tr>
<td style="font-size: 10pt" valign="top">
<code>class path</code></td>
Expand Down Expand Up @@ -252,17 +96,6 @@ <h2><a name="Deprecated-names">Deprecated names</a> and features</h2>
<td style="font-size: 10pt" valign="top">
<code>class path</code></td>
</tr>
<tr>
<td style="font-size: 10pt" valign="top">
<code>path.hpp</code></td>
<td style="font-size: 10pt" valign="top">
<code>typedef basic_path&lt;std::wstring, wpath_traits&gt; wpath</code></td>
<td style="font-size: 10pt" valign="top">
&#10004;</td>
<td style="font-size: 10pt" valign="top">
<i>Removed; use </i><code>class path</code><i> instead. Workaround provides
</i><code>typedef path wpath</code></td>
</tr>
<tr>
<td style="font-size: 10pt" valign="top">
<code>operations.hpp</code></td>
Expand All @@ -273,178 +106,6 @@ <h2><a name="Deprecated-names">Deprecated names</a> and features</h2>
<td style="font-size: 10pt" valign="top">
<i>Function removed</i></td>
</tr>
<tr>
<td style="font-size: 10pt" valign="top">
<code>operations.hpp</code></td>
<td style="font-size: 10pt" valign="top">
<p dir="ltr"><code>template &lt;class Path&gt;<br>
Path complete(const Path&amp; p,<br>
&nbsp;const Path&amp; base=<br>
&nbsp;&nbsp; initial_path&lt;Path&gt;())</code></td>
<td style="font-size: 10pt" valign="top">
&#10004;</td>
<td style="font-size: 10pt" valign="top">
<p dir="ltr"><code>path absolute(const path&amp; p, const path&amp; base=<br>
&nbsp; current_path())</code></td>
</tr>
<tr>
<td style="font-size: 10pt" valign="top">
<code>operations.hpp</code></td>
<td style="font-size: 10pt" valign="top">
<code>is_regular(file_status f)</code></td>
<td style="font-size: 10pt" valign="top">
&#10004;</td>
<td style="font-size: 10pt" valign="top">
<p dir="ltr">
<code>is_regular_file(file_status f)</code></td>
</tr>
<tr>
<td style="font-size: 10pt" valign="top">
<code>operations.hpp</code></td>
<td style="font-size: 10pt" valign="top">
<code>symbolic_link_exists(const path&amp; ph)</code></td>
<td style="font-size: 10pt" valign="top">
&nbsp;</td>
<td style="font-size: 10pt" valign="top">
<i>Function removed</i></td>
</tr>
<tr>
<td style="font-size: 10pt" valign="top">
<code>operations.hpp</code></td>
<td style="font-size: 10pt" valign="top">
<code>copy_directory(const path&amp; from, const path&amp; to)</code></td>
<td style="font-size: 10pt" valign="top">
&nbsp;</td>
<td style="font-size: 10pt" valign="top">
<i>Function removed, use <code>create_directory(const path&amp; to, const path&amp; from)</code> instead (note the reversed order of arguments)</i></td>
</tr>
<tr>
<td style="font-size: 10pt" valign="top">
<code>class directory_entry</code></td>
<td style="font-size: 10pt" valign="top">
<code>filename()</code></td>
<td style="font-size: 10pt" valign="top">
&#10004;</td>
<td style="font-size: 10pt" valign="top">
<i>Function removed, use </i><code>path().filename()</code><i> instead.</i></td>
</tr>
<tr>
<td style="font-size: 10pt" valign="top">
<code>class directory_entry</code></td>
<td style="font-size: 10pt" valign="top">
<code>leaf()</code></td>
<td style="font-size: 10pt" valign="top">
&#10004;</td>
<td style="font-size: 10pt" valign="top">
<i>Function removed, use </i><code>path().filename()</code><i> instead.</i></td>
</tr>
<tr>
<td style="font-size: 10pt" valign="top">
<code>class directory_entry</code></td>
<td style="font-size: 10pt" valign="top">
<code>string()</code></td>
<td style="font-size: 10pt" valign="top">
&#10004;</td>
<td style="font-size: 10pt" valign="top">
<i>Function removed, use </i><code>path().string()</code><i> instead.</i></td>
</tr>
<tr>
<td style="font-size: 10pt" valign="top"><code>class recursive_directory_iterator</code></td>
<td style="font-size: 10pt" valign="top"><code>level()</code></td>
<td style="font-size: 10pt" valign="top">&#10004;</td>
<td style="font-size: 10pt" valign="top"><code>depth()</code></td>
</tr>
<tr>
<td style="font-size: 10pt" valign="top"><code>class recursive_directory_iterator</code></td>
<td style="font-size: 10pt" valign="top"><code>no_push_pending()</code></td>
<td style="font-size: 10pt" valign="top">&#10004;</td>
<td style="font-size: 10pt" valign="top"><code>!recursion_pending()</code></td>
</tr>
<tr>
<td style="font-size: 10pt" valign="top"><code>class recursive_directory_iterator</code></td>
<td style="font-size: 10pt" valign="top"><code>no_push()</code></td>
<td style="font-size: 10pt" valign="top">&#10004;</td>
<td style="font-size: 10pt" valign="top"><code>disable_recursion_pending()</code></td>
</tr>
<tr>
<td style="font-size: 10pt" valign="top"><code>directory.hpp</code></td>
<td style="font-size: 10pt" valign="top"><code>enum class symlink_option</code></td>
<td style="font-size: 10pt" valign="top">&#10004;</td>
<td style="font-size: 10pt" valign="top"><i>Removed; use corresponding values of </i><code>enum class directory_options</code><i> instead.</i></td>
</tr>
<tr>
<td style="font-size: 10pt" valign="top">
<code>directory.hpp</code></td>
<td style="font-size: 10pt" valign="top">
<code>wrecursive_directory_iterator</code> typedef</td>
<td style="font-size: 10pt" valign="top">
&#10004;</td>
<td style="font-size: 10pt" valign="top">
<i>Removed; use </i><code>class recursive_directory_iterator</code><i> instead. Workaround provides
</i><code>typedef recursive_directory_iterator wrecursive_directory_iterator</code></td>
</tr>
<tr>
<td style="font-size: 10pt" valign="top">
<code>operations.hpp</code></td>
<td style="font-size: 10pt" valign="top">
The header provides <code>filesystem_error</code>, <code>file_status</code>, <code>directory_entry</code>, <code>directory_iterator</code>, <code>recursive_directory_iterator</code> and associated enums and functions.</td>
<td style="font-size: 10pt" valign="top">
&#10004;</td>
<td style="font-size: 10pt" valign="top">
<i>These components were moved to separate headers </i><code>exception.hpp</code><i>, </i><code>file_status.hpp</code><i> and </i><code>directory.hpp</code><i>.
The workaround is to include the new headers or </i><code>filesystem.hpp</code><i>. The new headers are still included by </i><code>operations.hpp</code><i> if
</i><code>BOOST_FILESYSTEM_NO_DEPRECATED</code><i> is not defined.</i></td>
</tr>
<tr>
<td style="font-size: 10pt" valign="top">
<code>path_traits.hpp</code></td>
<td style="font-size: 10pt" valign="top">
The header contains implementation details of class <code>path</code>.</td>
<td style="font-size: 10pt" valign="top">
&#10004;</td>
<td style="font-size: 10pt" valign="top">
<i>The header is deprecated and should not be used in user's code. Unavailable if </i><code>BOOST_FILESYSTEM_NO_DEPRECATED</code><i> is defined and will be permanently removed in a future release.</i></td>
</tr>
<tr>
<td style="font-size: 10pt" valign="top">
Macro definitions</td>
<td style="font-size: 10pt" valign="top">
<code>BOOST_WINDOW_API</code></td>
<td style="font-size: 10pt" valign="top">
&nbsp;</td>
<td style="font-size: 10pt" valign="top">
<i>No longer supported; API selection is always automatic.</i></td>
</tr>
<tr>
<td style="font-size: 10pt" valign="top">
Macro definitions</td>
<td style="font-size: 10pt" valign="top">
<code>BOOST_POSIX_API</code></td>
<td style="font-size: 10pt" valign="top">
&nbsp;</td>
<td style="font-size: 10pt" valign="top">
<i>No longer supported; API selection is always automatic.</i></td>
</tr>
<tr>
<td style="font-size: 10pt" valign="top">
Macro definitions</td>
<td style="font-size: 10pt" valign="top">
<code>BOOST_WINDOW_PATH</code></td>
<td style="font-size: 10pt" valign="top">
&nbsp;</td>
<td style="font-size: 10pt" valign="top">
<i>No longer supported; native path format selection is always automatic.</i></td>
</tr>
<tr>
<td style="font-size: 10pt" valign="top">
Macro definitions</td>
<td style="font-size: 10pt" valign="top">
<code>BOOST_POSIX_PATH</code></td>
<td style="font-size: 10pt" valign="top">
&nbsp;</td>
<td style="font-size: 10pt" valign="top">
<i>No longer supported; native path format selection is always automatic.</i></td>
</tr>
<tr>
<td style="font-size: 10pt" valign="top">
Build system</td>
Expand All @@ -471,7 +132,7 @@ <h3><code>initial_path</code> function</h3>
<hr>

<p>&copy; Copyright Beman Dawes, 2002-2005, 2010</p>
<p>&copy; Copyright Andrey Semashev, 2019-2021</p>
<p>&copy; Copyright Andrey Semashev, 2019-2024</p>
<p> Use, modification, and distribution are subject to the Boost Software
License, Version 1.0. See <a href="http://www.boost.org/LICENSE_1_0.txt">
www.boost.org/LICENSE_1_0.txt</a></p>
Expand Down

17 comments on commit 5df060e

@pdimov
Copy link
Member

@pdimov pdimov commented on 5df060e Jan 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This breaks quickbook:

tools/quickbook/src/actions.cpp:18:10: fatal error: boost/filesystem/convenience.hpp: No such file or directory
   18 | #include <boost/filesystem/convenience.hpp>
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
...failed updating 1 target...

What is the recommended replacement?

Why wasn't convenience.hpp issuing deprecation errors, if it were to be removed?

@pdimov
Copy link
Member

@pdimov pdimov commented on 5df060e Jan 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Never mind, the include was unnecessary, as nothing from the header was being used (FILESYSTEM_NO_DEPRECATED seems to be already defined.)

@pdimov
Copy link
Member

@pdimov pdimov commented on 5df060e Jan 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW, the other two breakages are in auto_index (which I fixed) and in Log :-)

libs/log/src/text_file_backend.cpp:46:10: fatal error: boost/filesystem/convenience.hpp: No such file or directory
   46 | #include <boost/filesystem/convenience.hpp>
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.

@Lastique
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why wasn't convenience.hpp issuing deprecation errors, if it were to be removed?

All symbols defined in the header were marked as deprecated. That the header itself wasn't was my omission, I guess, but there was no point in keeping an empty header after the symbols were removed.

@Lastique
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and in Log :-)

Thanks, will fix.

@mborland
Copy link
Member

@mborland mborland commented on 5df060e Jan 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inspect is also now broken: boostorg/inspect#18 because it is using the now removed normalize. Is replacing with canoncial the generally correct solution?

@Lastique
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inspect is also now broken: boostorg/inspect#18 because it is using the now removed normalize. Is replacing with canoncial the generally correct solution?

p.normalize() is equivalent to p = p.lexically_normal().

canonical is different in that it resolves symlinks and therefore requires p to exist.

@pdimov
Copy link
Member

@pdimov pdimov commented on 5df060e Jan 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a list with the removed APIs and their replacements? The deprecation warnings used to tell us that, but they have been removed now, so it's not easy to figure out what leaf or branch_path (or normalize) need to be changed to.

Maybe =delete-ing the functions would have been better as a transitory measure until everyone fixes them.

@Lastique
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's been years of deprecation warnings, that's enough of a transition period.

The suggested replacements were mentioned in the warnings and the docs up until now. Now these symbols no longer exist. Everyone who hasn't updated their code can either remain on an older Boost release, or use the information from the older release to update their code.

@pdimov
Copy link
Member

@pdimov pdimov commented on 5df060e Jan 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As the person who had to "update their code", except that it was other people's code, I can tell you from experience that that's not very convenient.

In fact removing the documentation in the exact moment it's needed the most is more than inconvenient, it's actively hostile.

@Lastique
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can understand the frustration, but the line has to be drawn somewhere.

@pdimov
Copy link
Member

@pdimov pdimov commented on 5df060e Jan 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, but you don't have to draw the line in the way that maximizes the frustration.

@Lastique
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Someone will be frustrated anyway because for one reason or another didn't bother to update the code for years despite the warnings. Oh well.

Anyway, what do you suggest me to do?

@pdimov
Copy link
Member

@pdimov pdimov commented on 5df060e Jan 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like you don't even bother to read what I write.

The majority of code using these constructs is in maintenance mode. The original author has long stopped paying attention to it. There's been nobody to update it for years. The code breaks today, and someone needs to fix it, going by the compile errors alone. He has no other context.

My suggestions have already been given. If you delete the functions instead of removing them, the deprecation warnings will point to the suggested replacement in the compile errors.

Failing that, the documentation should have a section listing the suggested replacements.

@Lastique
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like you don't even bother to read what I write.

I did, but I disagreed with your reasoning.

The majority of code using these constructs is in maintenance mode. The original author has long stopped paying attention to it. There's been nobody to update it for years. The code breaks today, and someone needs to fix it, going by the compile errors alone. He has no other context.

Sure, but does that mean I can no longer remove deprecated code from Boost.Filesystem?

We've been though this, multiple times. Most recently, when we deprecated and removed support for C++03, regardless of the level of support of downstream libraries. And surely enough, someone was frustrated and had to go ahead and update those libraries, even if that meant only cleaning up their CI.

Ideally, the one who makes the change should make an effort to update the downstream within Boost. Honestly, I didn't think anyone was still using the deprecated Boost.Filesystem APIs, so I didn't check. I probably should have checked anyway, sorry about that. But on the other hand, as far as I understand, I'm not obliged do this either, especially given that there was a generous deprecation period.

If you delete the functions instead of removing them, the deprecation warnings will point to the suggested replacement in the compile errors.

If the function is deleted, there are no deprecation warnings. There's a compilation error that doesn't mention the replacement. At best, there's a comment nearby suggesting a replacement. And you can't = delete enums, for example.

But most of all, this effectively means extending the deprecation period, which I simply don't want. This deprecated code is a burden which makes maintenance even more complicated than it already is.

Failing that, the documentation should have a section listing the suggested replacements.

Ok, I can restore the documentation. Although I don't think it'll make a difference. I consider the moment when the deprecation warnings were introduced was the time when it was most needed, not now.

@pdimov
Copy link
Member

@pdimov pdimov commented on 5df060e Jan 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the function is deleted, there are no deprecation warnings.

You are right, there aren't. But at least the message includes the function declaration, which is good enough (and better than nothing.)

https://godbolt.org/z/3efssaKGW

<source>: In function 'int main()':
<source>:7:6: error: use of deleted function 'void g()'
    7 |     g();
      |     ~^~
<source>:3:39: note: declared here
    3 | [[deprecated("please use f()")]] void g() = delete;
      |      

But most of all, this effectively means extending the deprecation period, which I simply don't want.

By one release; these are now errors, so they must be addressed. Deprecation warnings can be ignored for decades if the only "consumer" of code is CI and other tooling where one doesn't pay attention to successful builds.

Ok, I can restore the documentation. Although I don't think it'll make a difference.

Maybe not; people do pay attention to release notes, though, so it can't hurt to have it linked there.

@Lastique
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By one release; these are now errors, so they must be addressed.

Not everyone upgrade to every Boost release. And a missing function or a deleted function are basically equivalent anyway.

I have updated the docs with the description of the removed features.

Please sign in to comment.