Upgrade build infrastructure. Modernize tutorial examples to use C++11 to simplify code and make it easier to understand. Initial tutorial edits.

This commit is contained in:
Beman 2015-07-25 14:47:52 -04:00
parent 7701398d38
commit e9d72fa16c
10 changed files with 78 additions and 61 deletions

View File

@ -121,29 +121,26 @@ is well. A set of tutorial programs has been copied (by <code>setup</code>) to
and then built. You are encouraged to modify and experiment with them as the and then built. You are encouraged to modify and experiment with them as the
tutorial progresses. Just invoke the <code>bld</code> script again to rebuild.</p> tutorial progresses. Just invoke the <code>bld</code> script again to rebuild.</p>
<p>If something didn't work right, here are troubleshooting suggestions:</p> <p>If something didn't work right, here are some troubleshooting suggestions:</p>
<ul> <ul>
<li>The <code>bjam</code> program executable isn't being found. <li>If the <code>b2</code> program executable isn't being found, check your path environmental variable
Check your path environmental variable if it should have been found, or see
otherwise see
<a href="http://www.boost.org/more/getting_started/windows.html">Boost <a href="http://www.boost.org/more/getting_started/windows.html">Boost
Getting Started</a>.<br> Getting Started</a>.<br>
&nbsp;</li> &nbsp;</li>
<li>Look at <code>bjam.log</code> to try to spot an indication of the <li>Look at <code>b2.log</code> to try to spot an indication of the
problem.</li> problem.</li>
</ul> </ul>
<h2><a name="Reporting-size">Reporting the size of a file</a> - (<a href="../example/tut1.cpp">tut1.cpp</a>)</h2> <h2><a name="Reporting-size">Reporting the size of a file</a> - (<a href="../example/tut1.cpp">tut1.cpp</a>)</h2>
<p>Let's get started. One of the simplest things we can do is report the size of <p>Let's get started. Our first example program, <a href="../example/tut1.cpp">tut1.cpp</a>, reports the size of
a file.</p> a file.</p>
<table border="1" cellpadding="3" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF"> <table border="1" cellpadding="3" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF">
<tr> <tr>
<td> <td>
<pre><a href="../example/tut1.cpp">tut1.cpp</a></pre>
<blockquote>
<pre>#include &lt;iostream&gt; <pre>#include &lt;iostream&gt;
#include &lt;boost/filesystem.hpp&gt; #include &lt;boost/filesystem.hpp&gt;
using namespace boost::filesystem; using namespace boost::filesystem;
@ -158,7 +155,6 @@ int main(int argc, char* argv[])
std::cout &lt;&lt; argv[1] &lt;&lt; &quot; &quot; &lt;&lt; file_size(argv[1]) &lt;&lt; '\n'; std::cout &lt;&lt; argv[1] &lt;&lt; &quot; &quot; &lt;&lt; file_size(argv[1]) &lt;&lt; '\n';
return 0; return 0;
}</pre> }</pre>
</blockquote>
</td> </td>
</tr> </tr>
</table> </table>
@ -244,7 +240,8 @@ Aborted</pre>
<tr> <tr>
<td valign="top"> <td valign="top">
<pre>&gt;tut1 foo</pre> <pre>&gt;tut1 foo</pre>
<p><b><i>An exception is thrown; the exact form of the response depends on <p><b><i>An exception is thrown;<br>
the exact form of the response depends on
Windows system options.</i></b></td> Windows system options.</i></b></td>
</tr> </tr>
</table> </table>
@ -279,8 +276,8 @@ Aborted</pre>
<tr> <tr>
<td valign="top"> <td valign="top">
<pre>&gt;tut1 .</pre> <pre>&gt;tut1 .</pre>
<p><b><i>An exception is thrown; the exact form of the response depends on <p><b><i>An exception is thrown;<br>
Windows system options.</i></b></td> the exact form of the response depends on Windows system options.</i></b></td>
</tr> </tr>
</table> </table>
@ -300,14 +297,12 @@ described by their name is met. Otherwise they return <code>false</code>,
including when any element including when any element
of the path argument can't be found.</p> of the path argument can't be found.</p>
<p>tut2.cpp uses several of the status query functions to cope with non-existent <p><a href="../example/tut2.cpp">tut2.cpp</a> uses several of the status query functions to cope with non-existent
files and with different kinds of files:</p> files and with different kinds of files:</p>
<table border="1" cellpadding="3" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF"> <table border="1" cellpadding="3" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF">
<tr> <tr>
<td> <td>
<pre><a href="../example/tut2.cpp">tut2.cpp</a></pre>
<blockquote>
<pre>int main(int argc, char* argv[]) <pre>int main(int argc, char* argv[])
{ {
<a href="reference.html#class-path">path</a> p (argv[1]); // p reads clearer than argv[1] in the following code <a href="reference.html#class-path">path</a> p (argv[1]); // p reads clearer than argv[1] in the following code
@ -328,7 +323,6 @@ files and with different kinds of files:</p>
return 0; return 0;
}</pre> }</pre>
</blockquote>
</td> </td>
</tr> </tr>
</table> </table>
@ -407,7 +401,8 @@ Aborted</pre>
<pre>&gt;dir e:\ <pre>&gt;dir e:\
The device is not ready. The device is not ready.
&gt;tut2 e:\</pre> &gt;tut2 e:\</pre>
<p><b><i>An exception is thrown; the exact form of the response depends on <p dir="ltr"><b><i>An exception is thrown;<br>
the exact form of the response depends on
Windows system options.</i></b></td> Windows system options.</i></b></td>
</tr> </tr>
</table> </table>
@ -429,7 +424,7 @@ acts as the end iterator.</p>
<p>The value type of <code>directory_iterator</code> is <code> <p>The value type of <code>directory_iterator</code> is <code>
<a href="reference.html#directory_entry">directory_entry</a></code>. A <code> <a href="reference.html#directory_entry">directory_entry</a></code>. A <code>
directory_entry</code> object contains a <code>path</code> and <code><a href="reference.html#file_status">file_status</a></code> directory_entry</code> object contains <code>path</code> and <code><a href="reference.html#file_status">file_status</a></code>
information.&nbsp; A <code> information.&nbsp; A <code>
directory_entry</code> object directory_entry</code> object
can be used directly, but can also be passed to <code>path</code> arguments in function calls.</p> can be used directly, but can also be passed to <code>path</code> arguments in function calls.</p>
@ -437,13 +432,12 @@ can be used directly, but can also be passed to <code>path</code> arguments in f
<p>The other need is increased robustness in the face of the many kinds of <p>The other need is increased robustness in the face of the many kinds of
errors that can affect file system operations. We could do that at the level of errors that can affect file system operations. We could do that at the level of
each call to a Boost.Filesystem function (see <a href="#Error-reporting">Error each call to a Boost.Filesystem function (see <a href="#Error-reporting">Error
reporting</a>), but it is easier to supply an overall try/catch block.</p> reporting</a>), but for simplicity <a href="../example/tut3.cpp">tut3.cpp</a>
uses an overall try/catch block.</p>
<table border="1" cellpadding="3" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF"> <table border="1" cellpadding="3" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF">
<tr> <tr>
<td> <td>
<pre><a href="../example/tut3.cpp">tut3.cpp</a></pre>
<blockquote>
<pre>int main(int argc, char* argv[]) <pre>int main(int argc, char* argv[])
{ {
<a href="reference.html#class-path">path</a> p (argv[1]); // p reads clearer than argv[1] in the following code <a href="reference.html#class-path">path</a> p (argv[1]); // p reads clearer than argv[1] in the following code
@ -479,7 +473,6 @@ reporting</a>), but it is easier to supply an overall try/catch block.</p>
return 0; return 0;
}</pre> }</pre>
</blockquote>
</td> </td>
</tr> </tr>
</table> </table>
@ -574,10 +567,14 @@ boost::filesystem::status: The device is not ready: &quot;e:\&quot;</pre>
results ourselves. </li> results ourselves. </li>
</ul> </ul>
<p>Move on to <code>tut4.cpp</code> to see how those changes play out!</p> <p>The next sections show how how those changes play out, so read on!</p>
<h2><a name="Using-path-decomposition">Using path decomposition, plus sorting results</a> - (<a href="../example/tut4.cpp">tut4.cpp</a>)</h2> <h2><a name="Using-path-decomposition">Using path decomposition, plus sorting results</a> - (<a href="../example/tut4.cpp">tut4.cpp</a>)</h2>
<p>For directories, <a href="../example/tut4.cpp">tut4.cpp</a> builds a <code>
std::vector</code> of all the entries and then sorts it before writing to <code>
cout</code>.</p>
<table border="1" cellpadding="3" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF"> <table border="1" cellpadding="3" cellspacing="0" style="border-collapse: collapse" bordercolor="#111111" bgcolor="#D7EEFF">
<tr> <tr>
<td> <td>
@ -598,7 +595,7 @@ boost::filesystem::status: The device is not ready: &quot;e:\&quot;</pre>
{ {
cout &lt;&lt; p &lt;&lt; &quot; is a directory containing:\n&quot;; cout &lt;&lt; p &lt;&lt; &quot; is a directory containing:\n&quot;;
typedef vector&lt;path&gt; vec; // store paths, typedef std::vector&lt;path&gt; vec; // store paths,
vec v; // so we can sort them later vec v; // so we can sort them later
copy(directory_iterator(p), directory_iterator(), back_inserter(v)); copy(directory_iterator(p), directory_iterator(), back_inserter(v));
@ -1235,7 +1232,7 @@ It has a
<p>Distributed under the Boost Software License, Version 1.0. See <p>Distributed under 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> <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a></p>
<p>Revised <p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan -->23 July 2015<!--webbot bot="Timestamp" endspan i-checksum="18806" --></p> <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan -->24 July 2015<!--webbot bot="Timestamp" endspan i-checksum="18808" --></p>
</body> </body>

View File

@ -7,6 +7,9 @@
<ClCompile> <ClCompile>
<AdditionalIncludeDirectories>..\..\..\..\..</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\..\..\..\..</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link>
<AdditionalLibraryDirectories>..\..\..\..\..\stage\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup /> <ItemGroup />
</Project> </Project>

View File

@ -98,6 +98,9 @@
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
</Link> </Link>
<PostBuildEvent>
<Command>"$(TargetDir)\$(TargetName).exe" .</Command>
</PostBuildEvent>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile> <ClCompile>
@ -112,6 +115,9 @@
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
</Link> </Link>
<PostBuildEvent>
<Command>"$(TargetDir)\$(TargetName).exe" .</Command>
</PostBuildEvent>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile> <ClCompile>
@ -130,6 +136,9 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
</Link> </Link>
<PostBuildEvent>
<Command>"$(TargetDir)\$(TargetName).exe" .</Command>
</PostBuildEvent>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile> <ClCompile>
@ -148,6 +157,9 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
</Link> </Link>
<PostBuildEvent>
<Command>"$(TargetDir)\$(TargetName).exe" .</Command>
</PostBuildEvent>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\..\tut3.cpp" /> <ClCompile Include="..\..\tut3.cpp" />

View File

@ -98,6 +98,9 @@
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
</Link> </Link>
<PostBuildEvent>
<Command>"$(TargetDir)\$(TargetName).exe" .</Command>
</PostBuildEvent>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile> <ClCompile>
@ -112,6 +115,9 @@
<SubSystem>Console</SubSystem> <SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
</Link> </Link>
<PostBuildEvent>
<Command>"$(TargetDir)\$(TargetName).exe" .</Command>
</PostBuildEvent>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile> <ClCompile>
@ -130,6 +136,9 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
</Link> </Link>
<PostBuildEvent>
<Command>"$(TargetDir)\$(TargetName).exe" .</Command>
</PostBuildEvent>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile> <ClCompile>
@ -148,6 +157,9 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding> <EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
</Link> </Link>
<PostBuildEvent>
<Command>"$(TargetDir)\$(TargetName).exe" .</Command>
</PostBuildEvent>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\..\tut4.cpp" /> <ClCompile Include="..\..\tut4.cpp" />

View File

@ -3,5 +3,5 @@ rem Copyright Beman Dawes, 2010
rem Distributed under the Boost Software License, Version 1.0. rem Distributed under the Boost Software License, Version 1.0.
rem See www.boost.org/LICENSE_1_0.txt rem See www.boost.org/LICENSE_1_0.txt
bjam %* >bjam.log bjam %* >b2.log
find "error" <bjam.log find "error" <b2.log

View File

@ -4,5 +4,5 @@
# Distributed under the Boost Software License, Version 1.0. # Distributed under the Boost Software License, Version 1.0.
# See www.boost.org/LICENSE_1_0.txt # See www.boost.org/LICENSE_1_0.txt
bjam $* >bjam.log b2 $* >b2.log
grep "error" <bjam.log grep "error" <b2.log

View File

@ -18,8 +18,6 @@ int main(int argc, char* argv[])
std::cout << "Usage: tut0 path\n"; std::cout << "Usage: tut0 path\n";
return 1; return 1;
} }
std::cout << argv[1] << '\n'; std::cout << argv[1] << '\n';
return 0; return 0;
} }

View File

@ -20,18 +20,18 @@ int main(int argc, char* argv[])
return 1; return 1;
} }
path p (argv[1]); // p reads clearer than argv[1] in the following code path p(argv[1]); // avoid repeated path construction below
if (exists(p)) // does p actually exist? if (exists(p)) // does path p actually exist?
{ {
if (is_regular_file(p)) // is p a regular file? if (is_regular_file(p)) // is path p a regular file?
cout << p << " size is " << file_size(p) << '\n'; cout << p << " size is " << file_size(p) << '\n';
else if (is_directory(p)) // is p a directory? else if (is_directory(p)) // is path p a directory?
cout << p << " is a directory\n"; cout << p << " is a directory\n";
else else
cout << p << " exists, but is neither a regular file nor a directory\n"; cout << p << " exists, but is not a regular file or directory\n";
} }
else else
cout << p << " does not exist\n"; cout << p << " does not exist\n";

View File

@ -11,7 +11,7 @@
#include <iterator> #include <iterator>
#include <algorithm> #include <algorithm>
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
using namespace std; using std::cout;
using namespace boost::filesystem; using namespace boost::filesystem;
int main(int argc, char* argv[]) int main(int argc, char* argv[])
@ -22,26 +22,24 @@ int main(int argc, char* argv[])
return 1; return 1;
} }
path p (argv[1]); // p reads clearer than argv[1] in the following code path p (argv[1]);
try try
{ {
if (exists(p)) // does p actually exist? if (exists(p))
{ {
if (is_regular_file(p)) // is p a regular file? if (is_regular_file(p))
cout << p << " size is " << file_size(p) << '\n'; cout << p << " size is " << file_size(p) << '\n';
else if (is_directory(p)) // is p a directory? else if (is_directory(p))
{ {
cout << p << " is a directory containing:\n"; cout << p << " is a directory containing:\n";
copy(directory_iterator(p), directory_iterator(), // directory_iterator::value_type for (directory_entry& x : directory_iterator(p))
ostream_iterator<directory_entry>(cout, "\n")); // is directory_entry, which is cout << x.path() << '\n';
// converted to a path by the
// path stream inserter
} }
else else
cout << p << " exists, but is neither a regular file nor a directory\n"; cout << p << " exists, but is not a regular file or directory\n";
} }
else else
cout << p << " does not exist\n"; cout << p << " does not exist\n";

View File

@ -12,7 +12,7 @@
#include <vector> #include <vector>
#include <algorithm> #include <algorithm>
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
using namespace std; using std::cout;
using namespace boost::filesystem; using namespace boost::filesystem;
int main(int argc, char* argv[]) int main(int argc, char* argv[])
@ -23,34 +23,31 @@ int main(int argc, char* argv[])
return 1; return 1;
} }
path p (argv[1]); // p reads clearer than argv[1] in the following code path p (argv[1]);
try try
{ {
if (exists(p)) // does p actually exist? if (exists(p))
{ {
if (is_regular_file(p)) // is p a regular file? if (is_regular_file(p))
cout << p << " size is " << file_size(p) << '\n'; cout << p << " size is " << file_size(p) << '\n';
else if (is_directory(p)) // is p a directory? else if (is_directory(p))
{ {
cout << p << " is a directory containing:\n"; cout << p << " is a directory containing:\n";
typedef vector<path> vec; // store paths, std::vector<std::string> v;
vec v; // so we can sort them later
copy(directory_iterator(p), directory_iterator(), back_inserter(v)); for (auto&& x : directory_iterator(p))
v.push_back(x.path().filename().string());
sort(v.begin(), v.end()); // sort, since directory iteration std::sort(v.begin(), v.end());
// is not ordered on some file systems
for (vec::const_iterator it(v.begin()), it_end(v.end()); it != it_end; ++it) for (auto&& x : v)
{ cout << x << '\n';
cout << " " << *it << '\n';
}
} }
else else
cout << p << " exists, but is neither a regular file nor a directory\n"; cout << p << " exists, but is not a regular file or directory\n";
} }
else else
cout << p << " does not exist\n"; cout << p << " does not exist\n";