mirror of
https://github.com/boostorg/website.git
synced 2026-01-19 16:52:15 +00:00
297 lines
14 KiB
HTML
297 lines
14 KiB
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
|
|
|
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
|
<head>
|
|
<title>Boost Implementation Variations</title>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
<link rel="icon" href="/favicon.ico" type="image/ico" />
|
|
<link rel="stylesheet" type="text/css" href=
|
|
"/style-v2/section-community.css" />
|
|
<!--[if IE 7]> <style type="text/css"> body { behavior: url(/style-v2/csshover3.htc); } </style> <![endif]-->
|
|
<script defer data-domain="original.boost.org" src="https://plausible.io/js/script.js"></script></head><!--
|
|
Note: Editing website content is documented at:
|
|
https://www.boost.org/development/website_updating.html
|
|
-->
|
|
|
|
<body>
|
|
<div id="heading">
|
|
<!--#include virtual="/common/heading.html" -->
|
|
</div>
|
|
|
|
<div id="body">
|
|
<div id="body-inner">
|
|
<div id="content">
|
|
<div class="section" id="intro">
|
|
<div class="section-0">
|
|
<div class="section-title">
|
|
<h1>Boost Implementation Variations</h1>
|
|
</div>
|
|
|
|
<div class="section-body">
|
|
<h2>Separation of interface and implementation</h2>
|
|
|
|
<p>The interface specifications for boost.org library
|
|
components (as well as for quality software in general) are
|
|
conceptually separate from implementations of those interfaces.
|
|
This may not be obvious, particularly when a component is
|
|
implemented entirely within a header, but this separation of
|
|
interface and implementation is always assumed. From the
|
|
perspective of those concerned with software design,
|
|
portability, and standardization, the interface is what is
|
|
important, while the implementation is just a detail.</p>
|
|
|
|
<p>Dietmar Kühl, one of the original boost.org
|
|
contributors, comments "The main contribution is the interface,
|
|
which is augmented with an implementation, proving that it is
|
|
possible to implement the corresponding class and providing a
|
|
free implementation."</p>
|
|
|
|
<h2>Implementation variations</h2>
|
|
|
|
<p>There may be a need for multiple implementations of an
|
|
interface, to accommodate either platform dependencies or
|
|
performance tradeoffs. Examples of platform dependencies
|
|
include compiler shortcomings, file systems, thread mechanisms,
|
|
and graphical user interfaces. The classic example of a
|
|
performance tradeoff is a fast implementation that uses a lot
|
|
of memory versus a slower implementation which uses less
|
|
memory.</p>
|
|
|
|
<p>Boost libraries generally use a <a href=
|
|
"/doc/libs/release/libs/config/config.htm">configuration
|
|
header</a>, boost/config.hpp, to capture compiler and platform
|
|
dependencies. Although the use of boost/config.hpp is not
|
|
required, it is the preferred approach for simple configuration
|
|
problems.</p>
|
|
|
|
<h2>Boost policy</h2>
|
|
|
|
<p>The Boost policy is to avoid platform dependent variations
|
|
in interface specifications, but supply implementations which
|
|
are usable over a wide range of platforms and applications.
|
|
That means boost libraries will use the techniques below
|
|
described as appropriate for dealing with platform
|
|
dependencies.</p>
|
|
|
|
<p>The Boost policy toward implementation variations designed
|
|
to enhance performance is to avoid them unless the benefits
|
|
greatly exceed the full costs. The term "full costs" is
|
|
intended to include both tangible costs like extra maintenance,
|
|
and intangible cost like increased difficulty in user
|
|
understanding.</p>
|
|
|
|
<h2>Techniques for providing implementation variations</h2>
|
|
|
|
<p>Several techniques may be used to provide implementation
|
|
variations. Each is appropriate in some situations, and not
|
|
appropriate in other situations.</p>
|
|
|
|
<h3>Single general purpose implementation</h3>
|
|
|
|
<p>The first technique is to simply not provide implementation
|
|
variation at all. Instead, provide a single general-purpose
|
|
implementation, and forgo the increased complexity implied by
|
|
all other techniques.</p>
|
|
|
|
<p><strong>Appropriate:</strong> When it is possible to write a
|
|
single portable implementation which has reasonable performance
|
|
across a wide range of platforms. Particularly appropriate when
|
|
alternative implementations differ only in esoteric ways.</p>
|
|
|
|
<p><strong>Not appropriate:</strong> When implementation
|
|
requires platform specific features, or when there are multiple
|
|
implementation possible with widely differing performance
|
|
characteristics.</p>
|
|
|
|
<p>Beman Dawes comments "In design discussions, some
|
|
implementation is often alleged to be much faster than another,
|
|
yet a timing test discovers no significant difference. The
|
|
lesson is that while algorithmic differences may affect speed
|
|
dramatically, coding differences such as changing a class from
|
|
virtual to non-virtual members or removing a level of
|
|
indirection are unlikely to make any measurable difference
|
|
unless deep in an inner loop. And even in an inner loop, modern
|
|
CPUs often execute such competing code sequences in the same
|
|
number of clock cycles! A single general purpose implementation
|
|
is often just fine."</p>
|
|
|
|
<p>Or as Donald Knuth said, "Premature optimization is the root
|
|
of all evil." (Computing Surveys, vol 6, #4, p 268).</p>
|
|
|
|
<h3>Macros</h3>
|
|
|
|
<p>While the evils of macros are well known, there remain a few
|
|
cases where macros are the preferred solution:</p>
|
|
|
|
<ul>
|
|
<li>Preventing multiple inclusion of headers via #include
|
|
guards.</li>
|
|
|
|
<li>Passing minor configuration information from a
|
|
configuration header to other files.</li>
|
|
</ul>
|
|
|
|
<p><strong>Appropriate:</strong> For small compile-time
|
|
variations that would otherwise be costly or confusing to
|
|
install, use, or maintain. More appropriate to communicate
|
|
within and between library components than to communicate with
|
|
library users.</p>
|
|
|
|
<p><strong>Not appropriate:</strong> If other techniques will
|
|
do.</p>
|
|
|
|
<p>To minimize the negative aspects of macros:</p>
|
|
|
|
<ul>
|
|
<li>Only use macros when they are clearly superior to other
|
|
techniques. They should be viewed as a last resort.</li>
|
|
|
|
<li>Names should be all uppercase and begin with the
|
|
namespace name. This will minimize the chance of name
|
|
collisions. For example, the #include guard for a boost
|
|
header called foobar.h might be named BOOST_FOOBAR_H.</li>
|
|
</ul>
|
|
|
|
<h3>Separate files</h3>
|
|
|
|
<p>A library component can have multiple variations, each
|
|
contained in its own separate file or files. The files for the
|
|
most appropriate variation are copied to the appropriate
|
|
include or implementation directories at installation time.</p>
|
|
|
|
<p>The way to provide this approach in boost libraries is to
|
|
include specialized implementations as separate files in
|
|
separate sub-directories in the .ZIP distribution file. For
|
|
example, the structure within the .ZIP distribution file for a
|
|
library named foobar which has both default and specialized
|
|
variations might look something like:</p>
|
|
<pre>
|
|
foobar.h // The default header file
|
|
foobar.cpp // The default implementation file
|
|
readme.txt // Readme explains when to use which files
|
|
self_contained/foobar.h // A variation with everything in the header
|
|
linux/foobar.cpp // Implementation file to replace the default
|
|
win32/foobar.h // Header file to replace the default
|
|
win32/foobar.cpp // Implementation file to replace the default
|
|
</pre>
|
|
|
|
<p><strong>Appropriate:</strong> When different platforms
|
|
require different implementations, or when there are major
|
|
performance differences between possible implementations.</p>
|
|
|
|
<p><strong>Not appropriate:</strong> When it makes sense to use
|
|
more that one of the variations in the same installation.</p>
|
|
|
|
<h3>Separate components</h3>
|
|
|
|
<p>Rather than have several implementation variations of a
|
|
single component, supply several separate components. For
|
|
example, the Boost library currently supplies
|
|
<code>scoped_ptr</code> and <code>shared_ptr</code> classes
|
|
rather than a single <code>smart_ptr</code> class parameterized
|
|
to distinguish between the two cases. There are several ways to
|
|
make the component choice:</p>
|
|
|
|
<ul>
|
|
<li>Hardwired by the programmer during coding.</li>
|
|
|
|
<li>Chosen by programmer written runtime logic (trading off
|
|
some extra space, time, and program complexity for the
|
|
ability to select the implementation at run-time.)</li>
|
|
</ul>
|
|
|
|
<p><strong>Appropriate:</strong> When the interfaces for the
|
|
variations diverge, and when it is reasonable to use more than
|
|
one of the variations. When run-time selection of
|
|
implementation is called for.</p>
|
|
|
|
<p><strong>Not appropriate:</strong> When the variations are
|
|
data type, traits, or specialization variations which can be
|
|
better handled by making the component a template. Also not
|
|
appropriate when choice of variation is best done by some setup
|
|
or installation mechanism outside of the program itself. Thus
|
|
usually not appropriate to cope with platform differences.</p>
|
|
|
|
<p><strong>Note:</strong> There is a related technique where
|
|
the interface is specified as an abstract (pure virtual) base
|
|
class (or an interface definition language), and the
|
|
implementation choice is passed off to some third-party, such
|
|
as a dynamic-link library or object-request broker. While that
|
|
is a powerful technique, it is way beyond the scope of this
|
|
discussion.</p>
|
|
|
|
<h3>Template-based approaches</h3>
|
|
|
|
<p>Turning a class or function into a template is often an
|
|
elegant way to cope with variations. Template-based approaches
|
|
provide optimal space and time efficiency in return for
|
|
constraining the implementation selection to compile time.</p>
|
|
|
|
<p>Important template techniques include:</p>
|
|
|
|
<ul>
|
|
<li>Data type parameterization. This allows a single
|
|
component to operate on a variety of data types and is why
|
|
templates were originally invented.</li>
|
|
|
|
<li>Traits parameterization. If parameterization is complex,
|
|
bundling up aspects into a single traits helper class can
|
|
allow great variation while hiding messy details. The C++
|
|
Standard Library provides several examples of this idiom,
|
|
such as <code>iterator_traits<></code> (24.3.1
|
|
lib.iterator.traits) and <tt>char_traits<></tt> (21.2
|
|
lib.char.traits).</li>
|
|
|
|
<li>Specialization. A template parameter can be used purely
|
|
for the purpose of selecting a specialization. For
|
|
example:</li>
|
|
</ul>
|
|
<pre>
|
|
SomeClass<fast> my_fast_object; // fast and small are empty classes
|
|
SomeClass<small> my_small_object; // used just to select specialization
|
|
</pre>
|
|
|
|
<p><strong>Appropriate:</strong> When the need for variation is
|
|
due to data type or traits or is performance-related like
|
|
selecting among several algorithms, and when a program might
|
|
reasonably use more than one of the variations.</p>
|
|
|
|
<p><strong>Not appropriate:</strong> When the interfaces for
|
|
variations are different, or when choice of variation is best
|
|
done by some mechanism outside of the program itself. Thus
|
|
usually not appropriate to cope with platform differences.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="sidebar">
|
|
<!--#include virtual="/common/sidebar-common.html" -->
|
|
<!--#include virtual="/common/sidebar-community.html" -->
|
|
</div>
|
|
|
|
<div class="clear"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="footer">
|
|
<div id="footer-left">
|
|
<div id="revised">
|
|
<p>Revised $Date$</p>
|
|
</div>
|
|
|
|
<div id="copyright">
|
|
<p>Copyright Beman Dawes 2001.</p>
|
|
</div><!--#include virtual="/common/footer-license.html" -->
|
|
</div>
|
|
|
|
<div id="footer-right">
|
|
<!--#include virtual="/common/footer-banners.html" -->
|
|
</div>
|
|
|
|
<div class="clear"></div>
|
|
</div>
|
|
</body>
|
|
</html>
|