summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/utility
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/utility')
-rw-r--r--src/boost/libs/utility/Assignable.html109
-rw-r--r--src/boost/libs/utility/CMakeLists.txt27
-rw-r--r--src/boost/libs/utility/Collection.html534
-rw-r--r--src/boost/libs/utility/CopyConstructible.html185
-rw-r--r--src/boost/libs/utility/LessThanComparable.html210
-rw-r--r--src/boost/libs/utility/MultiPassInputIterator.html95
-rw-r--r--src/boost/libs/utility/OptionalPointee.html159
-rw-r--r--src/boost/libs/utility/README.md24
-rw-r--r--src/boost/libs/utility/call_traits.htm755
-rw-r--r--src/boost/libs/utility/checked_delete.html15
-rw-r--r--src/boost/libs/utility/compressed_pair.htm16
-rw-r--r--src/boost/libs/utility/enable_if.html15
-rw-r--r--src/boost/libs/utility/identity_type/index.html15
-rw-r--r--src/boost/libs/utility/identity_type/test/Jamfile.v216
-rw-r--r--src/boost/libs/utility/identity_type/test/abstract.cpp35
-rw-r--r--src/boost/libs/utility/identity_type/test/noncopyable.cpp25
-rw-r--r--src/boost/libs/utility/identity_type/test/paren.cpp35
-rw-r--r--src/boost/libs/utility/identity_type/test/template.cpp48
-rw-r--r--src/boost/libs/utility/identity_type/test/var.cpp26
-rw-r--r--src/boost/libs/utility/identity_type/test/var_error.cpp18
-rw-r--r--src/boost/libs/utility/in_place_factories.html296
-rw-r--r--src/boost/libs/utility/index.html50
-rw-r--r--src/boost/libs/utility/iterator_adaptors.htm11
-rw-r--r--src/boost/libs/utility/meta/libraries.json126
-rw-r--r--src/boost/libs/utility/operators.htm2144
-rw-r--r--src/boost/libs/utility/sublibs1
-rw-r--r--src/boost/libs/utility/test/Jamfile.v244
-rw-r--r--src/boost/libs/utility/test/base_from_member_ref_test.cpp29
-rw-r--r--src/boost/libs/utility/test/base_from_member_test.cpp593
-rw-r--r--src/boost/libs/utility/test/binary_test.cpp647
-rw-r--r--src/boost/libs/utility/test/call_traits_test.cpp418
-rw-r--r--src/boost/libs/utility/test/compressed_pair_final_test.cpp55
-rw-r--r--src/boost/libs/utility/test/compressed_pair_test.cpp387
-rw-r--r--src/boost/libs/utility/test/initialized_test.cpp116
-rw-r--r--src/boost/libs/utility/test/initialized_test_fail1.cpp33
-rw-r--r--src/boost/libs/utility/test/initialized_test_fail2.cpp37
-rw-r--r--src/boost/libs/utility/test/iterators_test.cpp322
-rw-r--r--src/boost/libs/utility/test/operators_test.cpp936
-rw-r--r--src/boost/libs/utility/test/result_of_test.cpp322
-rw-r--r--src/boost/libs/utility/test/string_ref_from_rvalue.cpp26
-rw-r--r--src/boost/libs/utility/test/string_ref_test1.cpp110
-rw-r--r--src/boost/libs/utility/test/string_ref_test2.cpp323
-rw-r--r--src/boost/libs/utility/test/string_ref_test_io.cpp184
-rw-r--r--src/boost/libs/utility/test/string_view_constexpr_test1.cpp115
-rw-r--r--src/boost/libs/utility/test/string_view_from_rvalue.cpp26
-rw-r--r--src/boost/libs/utility/test/string_view_test1.cpp120
-rw-r--r--src/boost/libs/utility/test/string_view_test2.cpp410
-rw-r--r--src/boost/libs/utility/test/string_view_test_io.cpp184
-rw-r--r--src/boost/libs/utility/test/value_init_test.cpp371
-rw-r--r--src/boost/libs/utility/test/value_init_test_fail1.cpp27
-rw-r--r--src/boost/libs/utility/test/value_init_test_fail2.cpp27
-rw-r--r--src/boost/libs/utility/test/value_init_test_fail3.cpp27
-rw-r--r--src/boost/libs/utility/test/value_init_workaround_test.cpp163
-rw-r--r--src/boost/libs/utility/throw_exception.html15
-rw-r--r--src/boost/libs/utility/utility.htm583
-rw-r--r--src/boost/libs/utility/value_init.htm514
56 files changed, 12154 insertions, 0 deletions
diff --git a/src/boost/libs/utility/Assignable.html b/src/boost/libs/utility/Assignable.html
new file mode 100644
index 000000000..d3b315765
--- /dev/null
+++ b/src/boost/libs/utility/Assignable.html
@@ -0,0 +1,109 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<html>
+<head>
+ <meta http-equiv="Content-Language" content="en-us">
+ <meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
+
+ <title>Assignable</title>
+</head>
+
+<body bgcolor="#FFFFFF" link="#0000EE" text="#000000" vlink="#551A8B" alink=
+"#FF0000">
+ <img src="../../boost.png" alt="C++ Boost" width="277" height=
+ "86"><br clear="none">
+
+ <h1>Assignable</h1>
+
+ <h3>Description</h3>
+
+ <p>A type is Assignable if it is possible to assign one object of the type
+ to another object of that type.</p>
+
+ <h3>Notation</h3>
+
+ <table summary="">
+ <tr>
+ <td valign="top"><tt>T</tt></td>
+
+ <td valign="top">is type that is a model of Assignable</td>
+ </tr>
+
+ <tr>
+ <td valign="top"><tt>t</tt></td>
+
+ <td valign="top">is an object of type <tt>T</tt></td>
+ </tr>
+
+ <tr>
+ <td valign="top"><tt>u</tt></td>
+
+ <td valign="top">is an object of type <tt>T</tt> or possibly <tt>const
+ T</tt></td>
+ </tr>
+ </table>
+
+ <h3>Definitions</h3>
+
+ <h3>Valid expressions</h3>
+
+ <table border summary="">
+ <tr>
+ <th>Name</th>
+
+ <th>Expression</th>
+
+ <th>Return type</th>
+
+ <th>Semantics</th>
+ </tr>
+
+ <tr>
+ <td valign="top">Assignment</td>
+
+ <td valign="top"><tt>t = u</tt></td>
+
+ <td valign="top"><tt>T&amp;</tt></td>
+
+ <td valign="top"><tt>t</tt> is equivalent to <tt>u</tt></td>
+ </tr>
+ </table>
+
+ <h3>Models</h3>
+
+ <ul>
+ <li><tt>int</tt></li>
+
+ <li><tt>std::pair</tt></li>
+ </ul>
+
+ <h3>See also</h3>
+
+ <p><a href=
+ "http://www.sgi.com/tech/stl/DefaultConstructible.html">DefaultConstructible</a>
+ and <a href="./CopyConstructible.html">CopyConstructible</a><br></p>
+ <hr>
+
+ <p><a href="http://validator.w3.org/check?uri=referer"><img border="0" src=
+ "../../doc/images/valid-html401.png" alt="Valid HTML 4.01 Transitional"
+ height="31" width="88"></a></p>
+
+ <p>Revised
+ <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->05 December, 2006<!--webbot bot="Timestamp" endspan i-checksum="38516" --></p>
+
+ <table summary="">
+ <tr valign="top">
+ <td nowrap><i>Copyright &copy; 2000</i></td>
+
+ <td><i><a href="http://www.lsc.nd.edu/~jsiek">Jeremy Siek</a>, Univ.of
+ Notre Dame (<a href=
+ "mailto:jsiek@lsc.nd.edu">jsiek@lsc.nd.edu</a>)</i></td>
+ </tr>
+ </table>
+
+ <p><i>Distributed under the Boost Software License, Version 1.0. (See
+ accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or
+ copy at <a href=
+ "http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)</i></p>
+</body>
+</html>
diff --git a/src/boost/libs/utility/CMakeLists.txt b/src/boost/libs/utility/CMakeLists.txt
new file mode 100644
index 000000000..25177b0d6
--- /dev/null
+++ b/src/boost/libs/utility/CMakeLists.txt
@@ -0,0 +1,27 @@
+# Copyright 2018 Peter Dimov
+# Copyright 2018 Andrey Semashev
+# Distributed under the Boost Software License, Version 1.0.
+# See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt
+
+# Partial (add_subdirectory only) and experimental CMake support
+# Subject to change; please do not rely on the contents of this file yet.
+
+cmake_minimum_required(VERSION 3.5)
+
+project(BoostUtility LANGUAGES CXX)
+
+add_library(boost_utility INTERFACE)
+add_library(Boost::utility ALIAS boost_utility)
+
+target_include_directories(boost_utility INTERFACE include)
+
+target_link_libraries(boost_utility
+ INTERFACE
+ Boost::config
+ Boost::container_hash
+ Boost::core
+ Boost::preprocessor
+ Boost::static_assert
+ Boost::throw_exception
+ Boost::type_traits
+)
diff --git a/src/boost/libs/utility/Collection.html b/src/boost/libs/utility/Collection.html
new file mode 100644
index 000000000..b92ddd6ee
--- /dev/null
+++ b/src/boost/libs/utility/Collection.html
@@ -0,0 +1,534 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<html>
+<head>
+ <meta http-equiv="Content-Language" content="en-us">
+ <meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
+
+ <title>Collection</title>
+</head>
+
+<body bgcolor="#FFFFFF" link="#0000EE" text="#000000" vlink="#551A8B" alink=
+"#FF0000">
+ <h1><img src="../../boost.png" alt="boost logo" width="277" align="middle"
+ height="86"><br>
+ Collection</h1>
+
+ <h3>Description</h3>
+
+ <p>A Collection is a <i>concept</i> similar to the STL <a href=
+ "http://www.sgi.com/tech/stl/Container.html">Container</a> concept. A
+ Collection provides iterators for accessing a range of elements and
+ provides information about the number of elements in the Collection.
+ However, a Collection has fewer requirements than a Container. The
+ motivation for the Collection concept is that there are many useful
+ Container-like types that do not meet the full requirements of Container,
+ and many algorithms that can be written with this reduced set of
+ requirements. To summarize the reduction in requirements:</p>
+
+ <ul>
+ <li>It is not required to "own" its elements: the lifetime of an element
+ in a Collection does not have to match the lifetime of the Collection
+ object, though the lifetime of the element should cover the lifetime of
+ the Collection object.</li>
+
+ <li>The semantics of copying a Collection object is not defined (it could
+ be a deep or shallow copy or not even support copying).</li>
+
+ <li>The associated reference type of a Collection does not have to be a
+ real C++ reference.</li>
+ </ul>Because of the reduced requirements, some care must be taken when
+ writing code that is meant to be generic for all Collection types. In
+ particular, a Collection object should be passed by-reference since
+ assumptions can not be made about the behaviour of the copy constructor.
+
+ <h3>Associated types</h3>
+
+ <table border summary="">
+ <tr>
+ <td valign="top">Value type</td>
+
+ <td valign="top"><tt>X::value_type</tt></td>
+
+ <td valign="top">The type of the object stored in a Collection. If the
+ Collection is <i>mutable</i> then the value type must be <a href=
+ "http://www.sgi.com/tech/stl/Assignable.html">Assignable</a>. Otherwise
+ the value type must be <a href=
+ "./CopyConstructible.html">CopyConstructible</a>.</td>
+ </tr>
+
+ <tr>
+ <td valign="top">Iterator type</td>
+
+ <td valign="top"><tt>X::iterator</tt></td>
+
+ <td valign="top">The type of iterator used to iterate through a
+ Collection's elements. The iterator's value type is expected to be the
+ Collection's value type. A conversion from the iterator type to the
+ const iterator type must exist. The iterator type must be an <a href=
+ "http://www.sgi.com/tech/stl/InputIterator.html">InputIterator</a>.</td>
+ </tr>
+
+ <tr>
+ <td valign="top">Const iterator type</td>
+
+ <td valign="top"><tt>X::const_iterator</tt></td>
+
+ <td valign="top">A type of iterator that may be used to examine, but
+ not to modify, a Collection's elements.</td>
+ </tr>
+
+ <tr>
+ <td valign="top">Reference type</td>
+
+ <td valign="top"><tt>X::reference</tt></td>
+
+ <td valign="top">A type that behaves like a reference to the
+ Collection's value type. <a href="#n1">[1]</a></td>
+ </tr>
+
+ <tr>
+ <td valign="top">Const reference type</td>
+
+ <td valign="top"><tt>X::const_reference</tt></td>
+
+ <td valign="top">A type that behaves like a const reference to the
+ Collection's value type.</td>
+ </tr>
+
+ <tr>
+ <td valign="top">Pointer type</td>
+
+ <td valign="top"><tt>X::pointer</tt></td>
+
+ <td valign="top">A type that behaves as a pointer to the Collection's
+ value type.</td>
+ </tr>
+
+ <tr>
+ <td valign="top">Distance type</td>
+
+ <td valign="top"><tt>X::difference_type</tt></td>
+
+ <td valign="top">A signed integral type used to represent the distance
+ between two of the Collection's iterators. This type must be the same
+ as the iterator's distance type.</td>
+ </tr>
+
+ <tr>
+ <td valign="top">Size type</td>
+
+ <td valign="top"><tt>X::size_type</tt></td>
+
+ <td valign="top">An unsigned integral type that can represent any
+ nonnegative value of the Collection's distance type.</td>
+ </tr>
+ </table>
+
+ <h3>Notation</h3>
+
+ <table summary="">
+ <tr>
+ <td valign="top"><tt>X</tt></td>
+
+ <td valign="top">A type that is a model of Collection.</td>
+ </tr>
+
+ <tr>
+ <td valign="top"><tt>a</tt>, <tt>b</tt></td>
+
+ <td valign="top">Object of type <tt>X</tt>.</td>
+ </tr>
+
+ <tr>
+ <td valign="top"><tt>T</tt></td>
+
+ <td valign="top">The value type of <tt>X</tt>.</td>
+ </tr>
+ </table>
+
+ <h3>Valid expressions</h3>
+
+ <p>The following expressions must be valid.</p>
+
+ <table border summary="">
+ <tr>
+ <th>Name</th>
+
+ <th>Expression</th>
+
+ <th>Return type</th>
+ </tr>
+
+ <tr>
+ <td valign="top">Beginning of range</td>
+
+ <td valign="top"><tt>a.begin()</tt></td>
+
+ <td valign="top"><tt>iterator</tt> if <tt>a</tt> is mutable,
+ <tt>const_iterator</tt> otherwise</td>
+ </tr>
+
+ <tr>
+ <td valign="top">End of range</td>
+
+ <td valign="top"><tt>a.end()</tt></td>
+
+ <td valign="top"><tt>iterator</tt> if <tt>a</tt> is mutable,
+ <tt>const_iterator</tt> otherwise</td>
+ </tr>
+
+ <tr>
+ <td valign="top">Size</td>
+
+ <td valign="top"><tt>a.size()</tt></td>
+
+ <td valign="top"><tt>size_type</tt></td>
+ </tr><!--
+<TR>
+<TD VAlign=top>
+Maximum size
+</TD>
+<TD VAlign=top>
+<tt>a.max_size()</tt>
+</TD>
+<TD VAlign=top>
+<tt>size_type</tt>
+</TD>
+</TR>
+-->
+
+ <tr>
+ <td valign="top">Empty Collection</td>
+
+ <td valign="top"><tt>a.empty()</tt></td>
+
+ <td valign="top">Convertible to <tt>bool</tt></td>
+ </tr>
+
+ <tr>
+ <td valign="top">Swap</td>
+
+ <td valign="top"><tt>a.swap(b)</tt></td>
+
+ <td valign="top"><tt>void</tt></td>
+ </tr>
+ </table>
+
+ <h3>Expression semantics</h3>
+
+ <table border summary="">
+ <tr>
+ <th>Name</th>
+
+ <th>Expression</th>
+
+ <th>Semantics</th>
+
+ <th>Postcondition</th>
+ </tr>
+
+ <tr>
+ <td valign="top">Beginning of range</td>
+
+ <td valign="top"><tt>a.begin()</tt></td>
+
+ <td valign="top">Returns an iterator pointing to the first element in
+ the Collection.</td>
+
+ <td valign="top"><tt>a.begin()</tt> is either dereferenceable or
+ past-the-end. It is past-the-end if and only if <tt>a.size() ==
+ 0</tt>.</td>
+ </tr>
+
+ <tr>
+ <td valign="top">End of range</td>
+
+ <td valign="top"><tt>a.end()</tt></td>
+
+ <td valign="top">Returns an iterator pointing one past the last element
+ in the Collection.</td>
+
+ <td valign="top"><tt>a.end()</tt> is past-the-end.</td>
+ </tr>
+
+ <tr>
+ <td valign="top">Size</td>
+
+ <td valign="top"><tt>a.size()</tt></td>
+
+ <td valign="top">Returns the size of the Collection, that is, its
+ number of elements.</td>
+
+ <td valign="top"><tt>a.size() &gt;= 0</tt></td>
+ </tr><!--
+<TR>
+<TD VAlign=top>
+Maximum size
+</TD>
+<TD VAlign=top>
+<tt>a.max_size()</tt>
+</TD>
+<TD VAlign=top>
+&nbsp;
+</TD>
+<TD VAlign=top>
+Returns the largest size that this Collection can ever have. <A href="#8">[8]</A>
+</TD>
+<TD VAlign=top>
+<tt>a.max_size() &gt;= 0 &amp;&amp; a.max_size() &gt;= a.size()</tt>
+</TD>
+</TR>
+ -->
+
+ <tr>
+ <td valign="top">Empty Collection</td>
+
+ <td valign="top"><tt>a.empty()</tt></td>
+
+ <td valign="top">Equivalent to <tt>a.size() == 0</tt>. (But possibly
+ faster.)</td>
+
+ <td valign="top">&nbsp;</td>
+ </tr>
+
+ <tr>
+ <td valign="top">Swap</td>
+
+ <td valign="top"><tt>a.swap(b)</tt></td>
+
+ <td valign="top">Equivalent to <tt>swap(a,b)</tt></td>
+
+ <td valign="top">&nbsp;</td>
+ </tr>
+ </table>
+
+ <h3>Complexity guarantees</h3>
+
+ <p><tt>begin()</tt> and <tt>end()</tt> are amortized constant time.</p>
+
+ <p><tt>size()</tt> is at most linear in the Collection's size.
+ <tt>empty()</tt> is amortized constant time.</p>
+
+ <p><tt>swap()</tt> is at most linear in the size of the two
+ collections.</p>
+
+ <h3>Invariants</h3>
+
+ <table border summary="">
+ <tr>
+ <td valign="top">Valid range</td>
+
+ <td valign="top">For any Collection <tt>a</tt>, <tt>[a.begin(),
+ a.end())</tt> is a valid range.</td>
+ </tr>
+
+ <tr>
+ <td valign="top">Range size</td>
+
+ <td valign="top"><tt>a.size()</tt> is equal to the distance from
+ <tt>a.begin()</tt> to <tt>a.end()</tt>.</td>
+ </tr>
+
+ <tr>
+ <td valign="top">Completeness</td>
+
+ <td valign="top">An algorithm that iterates through the range
+ <tt>[a.begin(), a.end())</tt> will pass through every element of
+ <tt>a</tt>.</td>
+ </tr>
+ </table>
+
+ <h3>Models</h3>
+
+ <ul>
+ <li><tt>array</tt></li>
+
+ <li><tt>array_ptr</tt></li>
+
+ <li><tt>vector&lt;bool&gt;</tt></li>
+ </ul>
+
+ <h3>Collection Refinements</h3>
+
+ <p>There are quite a few concepts that refine the Collection concept,
+ similar to the concepts that refine the Container concept. Here is a brief
+ overview of the refining concepts.</p>
+
+ <h4>ForwardCollection</h4>
+
+ <p>The elements are arranged in some order that does not change
+ spontaneously from one iteration to the next. As a result, a
+ ForwardCollection is <a href=
+ "http://www.sgi.com/tech/stl/EqualityComparable.html">EqualityComparable</a>
+ and <a href=
+ "http://www.sgi.com/tech/stl/LessThanComparable.html">LessThanComparable</a>.
+ In addition, the iterator type of a ForwardCollection is a
+ MultiPassInputIterator which is just an InputIterator with the added
+ requirements that the iterator can be used to make multiple passes through
+ a range, and that if <tt>it1 == it2</tt> and <tt>it1</tt> is
+ dereferenceable then <tt>++it1 == ++it2</tt>. The ForwardCollection also
+ has a <tt>front()</tt> method.</p>
+
+ <table border summary="">
+ <tr>
+ <th>Name</th>
+
+ <th>Expression</th>
+
+ <th>Return type</th>
+
+ <th>Semantics</th>
+ </tr>
+
+ <tr>
+ <td valign="top">Front</td>
+
+ <td valign="top"><tt>a.front()</tt></td>
+
+ <td valign="top"><tt>reference</tt> if <tt>a</tt> is mutable,<br>
+ <tt>const_reference</tt> otherwise.</td>
+
+ <td valign="top">Equivalent to <tt>*(a.begin())</tt>.</td>
+ </tr>
+ </table>
+
+ <h4>ReversibleCollection</h4>
+
+ <p>The container provides access to iterators that traverse in both
+ directions (forward and reverse). The iterator type must meet all of the
+ requirements of <a href=
+ "http://www.sgi.com/tech/stl/BidirectionalIterator.html">BidirectionalIterator</a>
+ except that the reference type does not have to be a real C++ reference.
+ The ReversibleCollection adds the following requirements to those of
+ ForwardCollection.</p>
+
+ <table border summary="">
+ <tr>
+ <th>Name</th>
+
+ <th>Expression</th>
+
+ <th>Return type</th>
+
+ <th>Semantics</th>
+ </tr>
+
+ <tr>
+ <td valign="top">Beginning of range</td>
+
+ <td valign="top"><tt>a.rbegin()</tt></td>
+
+ <td valign="top"><tt>reverse_iterator</tt> if <tt>a</tt> is mutable,
+ <tt>const_reverse_iterator</tt> otherwise.</td>
+
+ <td valign="top">Equivalent to
+ <tt>X::reverse_iterator(a.end())</tt>.</td>
+ </tr>
+
+ <tr>
+ <td valign="top">End of range</td>
+
+ <td valign="top"><tt>a.rend()</tt></td>
+
+ <td valign="top"><tt>reverse_iterator</tt> if <tt>a</tt> is mutable,
+ <tt>const_reverse_iterator</tt> otherwise.</td>
+
+ <td valign="top">Equivalent to
+ <tt>X::reverse_iterator(a.begin())</tt>.</td>
+ </tr>
+
+ <tr>
+ <td valign="top">Back</td>
+
+ <td valign="top"><tt>a.back()</tt></td>
+
+ <td valign="top"><tt>reference</tt> if <tt>a</tt> is mutable,<br>
+ <tt>const_reference</tt> otherwise.</td>
+
+ <td valign="top">Equivalent to <tt>*(--a.end())</tt>.</td>
+ </tr>
+ </table>
+
+ <h4>SequentialCollection</h4>
+
+ <p>The elements are arranged in a strict linear order. No extra methods are
+ required.</p>
+
+ <h4>RandomAccessCollection</h4>
+
+ <p>The iterators of a RandomAccessCollection satisfy all of the
+ requirements of <a href=
+ "http://www.sgi.com/tech/stl/RandomAccessIterator.html">RandomAccessIterator</a>
+ except that the reference type does not have to be a real C++ reference. In
+ addition, a RandomAccessCollection provides an element access operator.</p>
+
+ <table border summary="">
+ <tr>
+ <th>Name</th>
+
+ <th>Expression</th>
+
+ <th>Return type</th>
+
+ <th>Semantics</th>
+ </tr>
+
+ <tr>
+ <td valign="top">Element Access</td>
+
+ <td valign="top"><tt>a[n]</tt></td>
+
+ <td valign="top"><tt>reference</tt> if <tt>a</tt> is mutable,
+ <tt>const_reference</tt> otherwise.</td>
+
+ <td valign="top">Returns the nth element of the Collection. <tt>n</tt>
+ must be convertible to <tt>size_type</tt>. Precondition: <tt>0 &lt;= n
+ &lt; a.size()</tt>.</td>
+ </tr>
+ </table>
+
+ <h3>Notes</h3>
+
+ <p><a name="n1" id="n1">[1]</a> The reference type does not have to be a
+ real C++ reference. The requirements of the reference type depend on the
+ context within which the Collection is being used. Specifically it depends
+ on the requirements the context places on the value type of the Collection.
+ The reference type of the Collection must meet the same requirements as the
+ value type. In addition, the reference objects must be equivalent to the
+ value type objects in the collection (which is trivially true if they are
+ the same object). Also, in a mutable Collection, an assignment to the
+ reference object must result in an assignment to the object in the
+ Collection (again, which is trivially true if they are the same object, but
+ non-trivial if the reference type is a proxy class).</p>
+
+ <h3>See also</h3>
+
+ <p><a href=
+ "http://www.sgi.com/tech/stl/Container.html">Container</a><br></p>
+ <hr>
+
+ <p><a href="http://validator.w3.org/check?uri=referer"><img border="0" src=
+ "../../doc/images/valid-html401.png" alt="Valid HTML 4.01 Transitional"
+ height="31" width="88"></a></p>
+
+ <p>Revised
+ <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->05
+ December, 2006<!--webbot bot="Timestamp" endspan i-checksum="38516" --></p>
+
+ <table summary="">
+ <tr valign="top">
+ <td nowrap><i>Copyright &copy; 2000</i></td>
+
+ <td><i><a href="http://www.boost.org/people/jeremy_siek.htm">Jeremy
+ Siek</a>, Univ.of Notre Dame and C++ Library &amp; Compiler Group/SGI
+ (<a href="mailto:jsiek@engr.sgi.com">jsiek@engr.sgi.com</a>)</i></td>
+ </tr>
+ </table>
+
+ <p><i>Distributed under the Boost Software License, Version 1.0. (See
+ accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or
+ copy at <a href=
+ "http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)</i></p>
+</body>
+</html>
diff --git a/src/boost/libs/utility/CopyConstructible.html b/src/boost/libs/utility/CopyConstructible.html
new file mode 100644
index 000000000..6a7ce6557
--- /dev/null
+++ b/src/boost/libs/utility/CopyConstructible.html
@@ -0,0 +1,185 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<html>
+<head>
+ <meta http-equiv="Content-Language" content="en-us">
+ <meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
+
+ <title>Copy Constructible</title>
+</head>
+
+<body bgcolor="#FFFFFF" link="#0000EE" text="#000000" vlink="#551A8B" alink=
+"#FF0000">
+ <img src="../../boost.png" alt="C++ Boost" width="277" height=
+ "86"><br clear="none">
+
+ <h1>Copy Constructible</h1>
+
+ <h3>Description</h3>
+
+ <p>A type is Copy Constructible if it is possible to copy objects of that
+ type.</p>
+
+ <h3>Notation</h3>
+
+ <table summary="">
+ <tr>
+ <td valign="top"><tt>T</tt></td>
+
+ <td valign="top">is type that is a model of Copy Constructible</td>
+ </tr>
+
+ <tr>
+ <td valign="top"><tt>t</tt></td>
+
+ <td valign="top">is an object of type <tt>T</tt></td>
+ </tr>
+
+ <tr>
+ <td valign="top"><tt>u</tt></td>
+
+ <td valign="top">is an object of type <tt>const T</tt></td>
+ </tr>
+ </table>
+
+ <h3>Definitions</h3>
+
+ <h3>Valid expressions</h3>
+
+ <table border summary="">
+ <tr>
+ <th>Name</th>
+
+ <th>Expression</th>
+
+ <th>Return type</th>
+
+ <th>Semantics</th>
+ </tr>
+
+ <tr>
+ <td valign="top">Copy constructor</td>
+
+ <td valign="top"><tt>T(t)</tt></td>
+
+ <td valign="top"><tt>T</tt></td>
+
+ <td valign="top"><tt>t</tt> is equivalent to <tt>T(t)</tt></td>
+ </tr>
+
+ <tr>
+ <td valign="top">Copy constructor</td>
+
+ <td valign="top">
+ <pre>
+T(u)
+</pre>
+ </td>
+
+ <td valign="top"><tt>T</tt></td>
+
+ <td valign="top"><tt>u</tt> is equivalent to <tt>T(u)</tt></td>
+ </tr>
+
+ <tr>
+ <td valign="top">Destructor</td>
+
+ <td valign="top">
+ <pre>
+t.~T()
+</pre>
+ </td>
+
+ <td valign="top"><tt>T</tt></td>
+
+ <td valign="top">&nbsp;</td>
+ </tr>
+
+ <tr>
+ <td valign="top">Address Operator</td>
+
+ <td valign="top">
+ <pre>
+&amp;t
+</pre>
+ </td>
+
+ <td valign="top"><tt>T*</tt></td>
+
+ <td valign="top">denotes the address of <tt>t</tt></td>
+ </tr>
+
+ <tr>
+ <td valign="top">Address Operator</td>
+
+ <td valign="top">
+ <pre>
+&amp;u
+</pre>
+ </td>
+
+ <td valign="top"><tt>T*</tt></td>
+
+ <td valign="top">denotes the address of <tt>u</tt></td>
+ </tr>
+ </table>
+
+ <h3>Models</h3>
+
+ <ul>
+ <li><tt>int</tt></li>
+
+ <li><tt>std::pair</tt></li>
+ </ul>
+
+ <h3>Concept Checking Class</h3>
+ <pre>
+ template &lt;class T&gt;
+ struct CopyConstructibleConcept
+ {
+ void constraints() {
+ T a(b); // require copy constructor
+ T* ptr = &amp;a; // require address of operator
+ const_constraints(a);
+ ignore_unused_variable_warning(ptr);
+ }
+ void const_constraints(const T&amp; a) {
+ T c(a); // require const copy constructor
+ const T* ptr = &amp;a; // require const address of operator
+ ignore_unused_variable_warning(c);
+ ignore_unused_variable_warning(ptr);
+ }
+ T b;
+ };
+</pre>
+
+ <h3>See also</h3>
+
+ <p><a href="http://www.sgi.com/tech/stl/DefaultConstructible.html">Default
+ Constructible</a> and <a href="./Assignable.html">Assignable</a><br></p>
+ <hr>
+
+ <p><a href="http://validator.w3.org/check?uri=referer"><img border="0" src=
+ "../../doc/images/valid-html401.png" alt="Valid HTML 4.01 Transitional"
+ height="31" width="88"></a></p>
+
+ <p>Revised
+ <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->05
+ December, 2006<!--webbot bot="Timestamp" endspan i-checksum="38516" --></p>
+
+ <table summary="">
+ <tr valign="top">
+ <td nowrap><i>Copyright &copy; 2000</i></td>
+
+ <td><i><a href="http://www.lsc.nd.edu/~jsiek">Jeremy Siek</a>, Univ.of
+ Notre Dame (<a href=
+ "mailto:jsiek@lsc.nd.edu">jsiek@lsc.nd.edu</a>)</i></td>
+ </tr>
+ </table>
+
+ <p><i>Distributed under the Boost Software License, Version 1.0. (See
+ accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or
+ copy at <a href=
+ "http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)</i></p>
+</body>
+</html>
diff --git a/src/boost/libs/utility/LessThanComparable.html b/src/boost/libs/utility/LessThanComparable.html
new file mode 100644
index 000000000..15b938fc5
--- /dev/null
+++ b/src/boost/libs/utility/LessThanComparable.html
@@ -0,0 +1,210 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<html>
+<!--
+ == Copyright (c) 1996-1999
+ == Silicon Graphics Computer Systems, Inc.
+ ==
+ == Permission to use, copy, modify, distribute and sell this software
+ == and its documentation for any purpose is hereby granted without fee,
+ == provided that the above copyright notice appears in all copies and
+ == that both that copyright notice and this permission notice appear
+ == in supporting documentation. Silicon Graphics makes no
+ == representations about the suitability of this software for any
+ == purpose. It is provided "as is" without express or implied warranty.
+ ==
+ == Copyright (c) 1994
+ == Hewlett-Packard Company
+ ==
+ == Permission to use, copy, modify, distribute and sell this software
+ == and its documentation for any purpose is hereby granted without fee,
+ == provided that the above copyright notice appears in all copies and
+ == that both that copyright notice and this permission notice appear
+ == in supporting documentation. Hewlett-Packard Company makes no
+ == representations about the suitability of this software for any
+ == purpose. It is provided "as is" without express or implied warranty.
+ ==
+ -->
+
+<head>
+ <meta http-equiv="Content-Language" content="en-us">
+ <meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
+
+ <title>LessThanComparable</title>
+</head>
+
+<body bgcolor="#FFFFFF" link="#0000EE" text="#000000" vlink="#551A8B" alink=
+"#FF0000">
+ <img src="../../boost.png" alt="C++ Boost" width="277" height=
+ "86"><br clear="none">
+
+ <h1>LessThanComparable</h1>
+
+ <h3>Description</h3>
+
+ <p>A type is LessThanComparable if it is ordered: it must be possible to
+ compare two objects of that type using <tt>operator&lt;</tt>, and
+ <tt>operator&lt;</tt> must be a strict weak ordering relation.</p>
+
+ <h3>Refinement of</h3>
+
+ <h3>Associated types</h3>
+
+ <h3>Notation</h3>
+
+ <table summary="">
+ <tr>
+ <td valign="top"><tt>X</tt></td>
+
+ <td valign="top">A type that is a model of LessThanComparable</td>
+ </tr>
+
+ <tr>
+ <td valign="top"><tt>x</tt>, <tt>y</tt>, <tt>z</tt></td>
+
+ <td valign="top">Object of type <tt>X</tt></td>
+ </tr>
+ </table>
+
+ <h3>Definitions</h3>
+
+ <p>Consider the relation <tt>!(x &lt; y) &amp;&amp; !(y &lt; x)</tt>. If
+ this relation is transitive (that is, if <tt>!(x &lt; y) &amp;&amp; !(y
+ &lt; x) &amp;&amp; !(y &lt; z) &amp;&amp; !(z &lt; y)</tt> implies <tt>!(x
+ &lt; z) &amp;&amp; !(z &lt; x)</tt>), then it satisfies the mathematical
+ definition of an equivalence relation. In this case, <tt>operator&lt;</tt>
+ is a <i>strict weak ordering</i>.</p>
+
+ <p>If <tt>operator&lt;</tt> is a strict weak ordering, and if each
+ equivalence class has only a single element, then <tt>operator&lt;</tt> is
+ a <i>total ordering</i>.</p>
+
+ <h3>Valid expressions</h3>
+
+ <table border summary="">
+ <tr>
+ <th>Name</th>
+
+ <th>Expression</th>
+
+ <th>Type requirements</th>
+
+ <th>Return type</th>
+ </tr>
+
+ <tr>
+ <td valign="top">Less</td>
+
+ <td valign="top"><tt>x &lt; y</tt></td>
+
+ <td valign="top">&nbsp;</td>
+
+ <td valign="top">Convertible to <tt>bool</tt></td>
+ </tr>
+ </table>
+
+ <h3>Expression semantics</h3>
+
+ <table border summary="">
+ <tr>
+ <th>Name</th>
+
+ <th>Expression</th>
+
+ <th>Precondition</th>
+
+ <th>Semantics</th>
+
+ <th>Postcondition</th>
+ </tr>
+
+ <tr>
+ <td valign="top">Less</td>
+
+ <td valign="top"><tt>x &lt; y</tt></td>
+
+ <td valign="top"><tt>x</tt> and <tt>y</tt> are in the domain of
+ <tt>&lt;</tt></td>
+
+ <td valign="top">&nbsp;</td>
+ </tr>
+ </table>
+
+ <h3>Complexity guarantees</h3>
+
+ <h3>Invariants</h3>
+
+ <table border summary="">
+ <tr>
+ <td valign="top">Irreflexivity</td>
+
+ <td valign="top"><tt>x &lt; x</tt> must be false.</td>
+ </tr>
+
+ <tr>
+ <td valign="top">Antisymmetry</td>
+
+ <td valign="top"><tt>x &lt; y</tt> implies !(y &lt; x) <a href=
+ "#n2">[2]</a></td>
+ </tr>
+
+ <tr>
+ <td valign="top">Transitivity</td>
+
+ <td valign="top"><tt>x &lt; y</tt> and <tt>y &lt; z</tt> implies <tt>x
+ &lt; z</tt> <a href="#n3">[3]</a></td>
+ </tr>
+ </table>
+
+ <h3>Models</h3>
+
+ <ul>
+ <li>int</li>
+ </ul>
+
+ <h3>Notes</h3>
+
+ <p><a name="n1" id="n1">[1]</a> Only <tt>operator&lt;</tt> is fundamental;
+ the other inequality operators are essentially syntactic sugar.</p>
+
+ <p><a name="n2" id="n2">[2]</a> Antisymmetry is a theorem, not an axiom: it
+ follows from irreflexivity and transitivity.</p>
+
+ <p><a name="n3" id="n3">[3]</a> Because of irreflexivity and transitivity,
+ <tt>operator&lt;</tt> always satisfies the definition of a <i>partial
+ ordering</i>. The definition of a <i>strict weak ordering</i> is stricter,
+ and the definition of a <i>total ordering</i> is stricter still.</p>
+
+ <h3>See also</h3>
+
+ <p><a href=
+ "http://www.sgi.com/tech/stl/EqualityComparable.html">EqualityComparable</a>,
+ <a href=
+ "http://www.sgi.com/tech/stl/StrictWeakOrdering.html">StrictWeakOrdering</a><br>
+ </p>
+ <hr>
+
+ <p><a href="http://validator.w3.org/check?uri=referer"><img border="0" src=
+ "../../doc/images/valid-html401.png" alt="Valid HTML 4.01 Transitional"
+ height="31" width="88"></a></p>
+
+ <p>Revised
+ <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->05
+ December, 2006<!--webbot bot="Timestamp" endspan i-checksum="38516" --></p>
+
+ <table summary="">
+ <tr valign="top">
+ <td nowrap><i>Copyright &copy; 2000</i></td>
+
+ <td><i><a href="http://www.lsc.nd.edu/~jsiek">Jeremy Siek</a>, Univ.of
+ Notre Dame (<a href=
+ "mailto:jsiek@lsc.nd.edu">jsiek@lsc.nd.edu</a>)</i></td>
+ </tr>
+ </table>
+
+ <p><i>Distributed under the Boost Software License, Version 1.0. (See
+ accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or
+ copy at <a href=
+ "http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)</i></p>
+</body>
+</html>
diff --git a/src/boost/libs/utility/MultiPassInputIterator.html b/src/boost/libs/utility/MultiPassInputIterator.html
new file mode 100644
index 000000000..e331ca3aa
--- /dev/null
+++ b/src/boost/libs/utility/MultiPassInputIterator.html
@@ -0,0 +1,95 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<html>
+<head>
+ <meta http-equiv="Content-Language" content="en-us">
+ <meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
+
+ <title>MultiPassInputIterator</title>
+</head>
+
+<body bgcolor="#FFFFFF" link="#0000EE" text="#000000" vlink="#551A8B" alink=
+"#FF0000">
+ <img src="../../boost.png" alt="C++ Boost" width="277" height=
+ "86"><br clear="none">
+
+ <h2><a name="concept:MultiPassInputIterator" id=
+ "concept:MultiPassInputIterator"></a> Multi-Pass Input Iterator</h2>
+
+ <p>This concept is a refinement of <a href=
+ "http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a>, adding
+ the requirements that the iterator can be used to make multiple passes
+ through a range, and that if <tt>it1 == it2</tt> and <tt>it1</tt> is
+ dereferenceable then <tt>++it1 == ++it2</tt>. The Multi-Pass Input Iterator
+ is very similar to the <a href=
+ "http://www.sgi.com/tech/stl/ForwardIterator.html">Forward Iterator</a>.
+ The only difference is that a <a href=
+ "http://www.sgi.com/tech/stl/ForwardIterator.html">Forward Iterator</a>
+ requires the <tt>reference</tt> type to be <tt>value_type&amp;</tt>,
+ whereas MultiPassInputIterator is like <a href=
+ "http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a> in that
+ the <tt>reference</tt> type merely has to be convertible to
+ <tt>value_type</tt>.</p>
+
+ <h3>Design Notes</h3>
+
+ <p>comments by Valentin Bonnard:</p>
+
+ <p>I think that introducing Multi-Pass Input Iterator isn't the right
+ solution. Do you also want to define Multi-Pass Bidirectionnal Iterator and
+ Multi-Pass Random Access Iterator ? I don't, definitly. It only confuses
+ the issue. The problem lies into the existing hierarchy of iterators, which
+ mixes movabillity, modifiabillity and lvalue-ness, and these are clearly
+ independant.</p>
+
+ <p>The terms Forward, Bidirectionnal and Random Access are about
+ movabillity and shouldn't be used to mean anything else. In a completly
+ orthogonal way, iterators can be immutable, mutable, or neither. Lvalueness
+ of iterators is also orthogonal with immutabillity. With these clean
+ concepts, your Multi-Pass Input Iterator is just called a Forward
+ Iterator.</p>
+
+ <p>Other translations are:<br>
+ std::Forward Iterator -&gt; ForwardIterator &amp; Lvalue Iterator<br>
+ std::Bidirectionnal Iterator -&gt; Bidirectionnal Iterator &amp; Lvalue
+ Iterator<br>
+ std::Random Access Iterator -&gt; Random Access Iterator &amp; Lvalue
+ Iterator<br></p>
+
+ <p>Note that in practice the only operation not allowed on my Forward
+ Iterator which is allowed on std::Forward Iterator is <tt>&amp;*it</tt>. I
+ think that <tt>&amp;*</tt> is rarely needed in generic code.</p>
+
+ <p>reply by Jeremy Siek:</p>
+
+ <p>The above analysis by Valentin is right on. Of course, there is the
+ problem with backward compatibility. The current STL implementations are
+ based on the old definition of Forward Iterator. The right course of action
+ is to get Forward Iterator, etc. changed in the C++ standard. Once that is
+ done we can drop Multi-Pass Input Iterator.<br></p>
+ <hr>
+
+ <p><a href="http://validator.w3.org/check?uri=referer"><img border="0" src=
+ "../../doc/images/valid-html401.png" alt="Valid HTML 4.01 Transitional"
+ height="31" width="88"></a></p>
+
+ <p>Revised
+ <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B, %Y" startspan -->05
+ December, 2006<!--webbot bot="Timestamp" endspan i-checksum="38516" --></p>
+
+ <table summary="">
+ <tr valign="top">
+ <td nowrap><i>Copyright &copy; 2000</i></td>
+
+ <td><i><a href="http://www.lsc.nd.edu/~jsiek">Jeremy Siek</a>, Univ.of
+ Notre Dame (<a href=
+ "mailto:jsiek@lsc.nd.edu">jsiek@lsc.nd.edu</a>)</i></td>
+ </tr>
+ </table>
+
+ <p><i>Distributed under the Boost Software License, Version 1.0. (See
+ accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or
+ copy at <a href=
+ "http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>)</i></p>
+</body>
+</html>
diff --git a/src/boost/libs/utility/OptionalPointee.html b/src/boost/libs/utility/OptionalPointee.html
new file mode 100644
index 000000000..c3c7e44eb
--- /dev/null
+++ b/src/boost/libs/utility/OptionalPointee.html
@@ -0,0 +1,159 @@
+<HTML>
+<Head>
+<Title>OptionalPointee Concept</Title>
+</HEAD>
+<BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"
+ ALINK="#ff0000">
+<IMG SRC="../../boost.png"
+ ALT="C++ Boost" width="277" height="86">
+<!--end header-->
+<BR Clear>
+<H1>Concept: OptionalPointee</H1>
+
+<h3>Description</h3>
+A type is a model of <i>OptionalPointee</i> if it points to (or refers to) a value
+that may not exist. That is, if it has a <b>pointee</b> which might be <b>valid</b>
+(existent) or <b>invalid</b> (inexistent); and it is possible to test whether the
+pointee is valid or not.
+This model does <u>not</u> imply pointer semantics: i.e., it does not imply shallow copy nor
+aliasing.
+<h3>Notation</h3>
+<Table>
+ <TR>
+ <TD VAlign=top> <tt>T</tt> </TD>
+ <TD VAlign=top> is a type that is a model of OptionalPointee</TD>
+ </TR>
+ <TR>
+ <TD VAlign=top> <tt>t</tt> </TD>
+ <TD VAlign=top> is an object of type <tt>T</tt> or possibly <tt>const T</tt></TD>
+ </tr>
+</table>
+<h3>Definitions</h3>
+<h3>Valid expressions</h3>
+<Table border>
+ <TR>
+ <TH> Name </TH>
+ <TH> Expression </TH>
+ <TH> Return type </TH>
+ <TH> Semantics </TH>
+ </TR>
+ <TR>
+ <TD VAlign=top>Value Access</TD>
+ <TD VAlign=top>&nbsp;<tt>*t</tt></TD>
+ <TD VAlign=top>&nbsp;<tt>T&amp;</tt></TD>
+ <TD VAlign=top>If the pointee is valid returns a reference to
+ the pointee.<br>
+ If the pointee is invalid the result is <i>undefined</i>.</TD>
+ <TD VAlign=top> </TD>
+ </TR>
+ <TR>
+ <TD VAlign=top>Value Access</TD>
+ <TD VAlign=top>&nbsp;<tt>t-><i>xyz</i></tt></TD>
+ <TD VAlign=top>&nbsp;<tt>T*</tt></TD>
+ <TD VAlign=top>If the pointee is valid returns a builtin pointer to the pointee.<br>
+ If the pointee is invalid the result is <i>undefined</i> (It might not even return NULL).<br>
+ </TD>
+ <TD VAlign=top> </TD>
+ </TR>
+ <TR>
+ <TD VAlign=top>Validity Test</TD>
+ <TD VAlign=top>&nbsp;<tt>bool(t)</tt></TD>
+ <TD VAlign=top>&nbsp;bool </TD>
+ <TD VAlign=top>If the pointee is valid returns true.<br>
+ If the pointee is invalid returns false.</TD>
+ <TD VAlign=top></TD>
+ </TR>
+ <TR>
+ <TD VAlign=top>Invalidity Test</TD>
+ <TD VAlign=top>&nbsp;<tt>!t</tt></TD>
+ <TD VAlign=top>&nbsp;bool </TD>
+ <TD VAlign=top>If the pointee is valid returns false.<br>
+ If the pointee is invalid returns true.</TD>
+ <TD VAlign=top></TD>
+ </TR>
+</table>
+
+
+<h3>Models</h3>
+
+<UL>
+ <LI><tt>pointers, both builtin and smart.</tt>
+ <LI><tt>boost::optional&lt;&gt;</tt>
+</UL>
+
+<HR>
+<h3>OptionalPointee and relational operations</h3>
+<p>This concept does not define any particular semantic for relational operations, therefore,
+a type which models this concept might have either shallow or deep relational semantics.<br>
+For instance, pointers, which are models of OptionalPointee, have shallow relational operators:
+comparisons of pointers do not involve comparisons of pointees.
+This makes sense for pointers because they have shallow copy semantics.<br>
+But boost::optional&lt;T&gt;, on the other hand, which is also a model of OptionalPointee, has
+deep-copy and deep-relational semantics.<br>
+If generic code is written for this concept, it is important not to use relational
+operators directly because the semantics might be different depending on the actual type.<br>
+Still, the concept itsef can be used to define <i>deep</i> relational tests that can
+be used in generic code with any type which models OptionalPointee:</p>
+<a name="equal"></a>
+<p><u>Equivalence relation:</u></p>
+<pre>template&lt;class OptionalPointee&gt;
+inline
+bool equal_pointees ( OptionalPointee const&amp; x, OptionalPointee const&amp; y )
+{
+ return (!x) != (!y) ? false : ( !x ? true : (*x) == (*y) ) ;
+}
+template&lt;class OptionalPointee&gt;
+struct equal_pointees_t : std::binary_function&lt;OptionalPointee,OptionalPointee,bool&gt;
+{
+ bool operator() ( OptionalPointee const& x, OptionalPointee const& y ) const
+ { return equal_pointees(x,y) ; }
+} ;
+</pre>
+<p>The preceding generic function and function object have the following semantics:<br>
+If both <b>x</b> and <b>y</b> have valid pointees, it compares values via <code>(*x == *y)</code>.<br>
+If only one has a valid pointee, returns <code>false</code>.<br>
+If both have invalid pointees, returns <code>true</code>.</p>
+<a name="less"></a>
+<p><u>Less-than relation:</u></p>
+<pre>template&lt;class OptionalPointee&gt;
+inline
+bool less_pointees ( OptionalPointee const&amp; x, OptionalPointee const&amp; y )
+{
+ return !y ? false : ( !x ? true : (*x) < (*y) ) ;
+}
+template&lt;class OptionalPointee&gt;
+struct less_pointees_t : std::binary_function&lt;OptionalPointee,OptionalPointee,bool&gt;
+{
+ bool operator() ( OptionalPointee const& x, OptionalPointee const& y ) const
+ { return less_pointees(x,y) ; }
+} ;
+</pre>
+<p>The preceding generic function and function object have the following semantics:<br>
+If <b>y</b> has an invalid pointee, returns <code>false</code>.<br>
+Else, if <b>x</b> has an invalid pointee, returns <code>true</code>.<br>
+Else, ( <b>x</b> and <b>y</b> have valid pointees), compares values via <code>(*x &lt;
+*y).</code></p>
+<p><br>
+All these functions and function
+objects are is implemented in <a href="../../boost/utility/compare_pointees.hpp">compare_pointees.hpp</a></p>
+<p>Notice that OptionalPointee does not imply aliasing (and optional&lt;&gt; for instance does not alias);
+so direct usage of relational operators with the implied aliasing of shallow semantics
+-as with pointers- should not be used with generic code written for this concept.</p>
+
+<h3>Acknowledgements</h3>
+<p>Based on the original concept developed by Augustus Saunders.
+
+<br>
+</p>
+<HR>
+<TABLE>
+<TR valign=top>
+<TD nowrap>Copyright &copy 2003</TD><TD>
+<A HREF="mailto:fernando_cacciola@hotmail.com">Fernando Cacciola</A>
+</TD></TR></TABLE>
+
+<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>
+
+</BODY>
+</HTML>
diff --git a/src/boost/libs/utility/README.md b/src/boost/libs/utility/README.md
new file mode 100644
index 000000000..49d3c288d
--- /dev/null
+++ b/src/boost/libs/utility/README.md
@@ -0,0 +1,24 @@
+# ![Boost.Utility](doc/logo.png)
+
+Boost.Utility, part of collection of the [Boost C++ Libraries](https://github.com/boostorg), provides a number of smaller components, too small to be called libraries in their own right. See the documentation for the list of components.
+
+### Directories
+
+* **doc** - Documentation sources
+* **include** - Interface headers of Boost.Utility
+* **test** - Boost.Utility unit tests
+
+### More information
+
+* [Documentation](https://boost.org/libs/utility)
+* [Report bugs](https://github.com/boostorg/utility/issues/new). Be sure to mention Boost version, Boost.Utility component, platform and compiler you're using. A small compilable code sample to reproduce the problem is always good as well.
+* Submit your patches as pull requests against **develop** branch. Note that by submitting patches you agree to license your modifications under the [Boost Software License, Version 1.0](https://www.boost.org/LICENSE_1_0.txt).
+
+### Build status
+
+Master: [![Travis CI](https://travis-ci.org/boostorg/utility.svg?branch=master)](https://travis-ci.org/boostorg/utility)
+Develop: [![Travis CI](https://travis-ci.org/boostorg/utility.svg?branch=develop)](https://travis-ci.org/boostorg/utility)
+
+### License
+
+Distributed under the [Boost Software License, Version 1.0](https://www.boost.org/LICENSE_1_0.txt).
diff --git a/src/boost/libs/utility/call_traits.htm b/src/boost/libs/utility/call_traits.htm
new file mode 100644
index 000000000..b4fe3ee90
--- /dev/null
+++ b/src/boost/libs/utility/call_traits.htm
@@ -0,0 +1,755 @@
+<html>
+
+<head>
+<meta http-equiv="Content-Type"
+content="text/html; charset=iso-8859-1">
+<meta name="Template"
+content="C:\PROGRAM FILES\MICROSOFT OFFICE\OFFICE\html.dot">
+<meta name="GENERATOR" content="Microsoft FrontPage Express 2.0">
+<title>Call Traits</title>
+</head>
+
+<body bgcolor="#FFFFFF" text="#000000" link="#0000FF"
+vlink="#800080">
+
+<h1><img src="../../boost.png" width="276" height="86">Header
+&lt;<a href="../../boost/detail/call_traits.hpp">boost/call_traits.hpp</a>&gt;</h1>
+
+<p>All of the contents of &lt;boost/call_traits.hpp&gt; are
+defined inside namespace boost.</p>
+
+<p>The template class call_traits&lt;T&gt; encapsulates the
+&quot;best&quot; method to pass a parameter of some type T to or
+from a function, and consists of a collection of typedefs defined
+as in the table below. The purpose of call_traits is to ensure
+that problems like &quot;<a href="#refs">references to references</a>&quot;
+never occur, and that parameters are passed in the most efficient
+manner possible (see <a href="#examples">examples</a>). In each
+case if your existing practice is to use the type defined on the
+left, then replace it with the call_traits defined type on the
+right. </p>
+
+<p>Note that for compilers that do not support either partial
+specialization or member templates, no benefit will occur from
+using call_traits: the call_traits defined types will always be
+the same as the existing practice in this case. In addition if
+only member templates and not partial template specialisation is
+support by the compiler (for example Visual C++ 6) then
+call_traits can not be used with array types (although it can be
+used to solve the reference to reference problem).</p>
+
+<table border="0" cellpadding="7" cellspacing="1" width="797">
+ <tr>
+ <td valign="top" width="17%" bgcolor="#008080"><p
+ align="center">Existing practice</p>
+ </td>
+ <td valign="top" width="35%" bgcolor="#008080"><p
+ align="center">call_traits equivalent</p>
+ </td>
+ <td valign="top" width="32%" bgcolor="#008080"><p
+ align="center">Description</p>
+ </td>
+ <td valign="top" width="16%" bgcolor="#008080"><p
+ align="center">Notes</p>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" width="17%"><p align="center">T<br>
+ (return by value)</p>
+ </td>
+ <td valign="top" width="35%"><p align="center"><code>call_traits&lt;T&gt;::value_type</code></p>
+ </td>
+ <td valign="top" width="32%">Defines a type that
+ represents the &quot;value&quot; of type T. Use this for
+ functions that return by value, or possibly for stored
+ values of type T.</td>
+ <td valign="top" width="16%"><p align="center">2</p>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" width="17%"><p align="center">T&amp;<br>
+ (return value)</p>
+ </td>
+ <td valign="top" width="35%"><p align="center"><code>call_traits&lt;T&gt;::reference</code></p>
+ </td>
+ <td valign="top" width="32%">Defines a type that
+ represents a reference to type T. Use for functions that
+ would normally return a T&amp;.</td>
+ <td valign="top" width="16%"><p align="center">1</p>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" width="17%"><p align="center">const
+ T&amp;<br>
+ (return value)</p>
+ </td>
+ <td valign="top" width="35%"><p align="center"><code>call_traits&lt;T&gt;::const_reference</code></p>
+ </td>
+ <td valign="top" width="32%">Defines a type that
+ represents a constant reference to type T. Use for
+ functions that would normally return a const T&amp;.</td>
+ <td valign="top" width="16%"><p align="center">1</p>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" width="17%"><p align="center">const
+ T&amp;<br>
+ (function parameter)</p>
+ </td>
+ <td valign="top" width="35%"><p align="center"><code>call_traits&lt;T&gt;::param_type</code></p>
+ </td>
+ <td valign="top" width="32%">Defines a type that
+ represents the &quot;best&quot; way to pass a parameter
+ of type T to a function.</td>
+ <td valign="top" width="16%"><p align="center">1,3</p>
+ </td>
+ </tr>
+</table>
+
+<p>Notes:</p>
+
+<ol>
+ <li>If T is already reference type, then call_traits is
+ defined such that <a href="#refs">references to
+ references</a> do not occur (requires partial
+ specialization).</li>
+ <li>If T is an array type, then call_traits defines <code>value_type</code>
+ as a &quot;constant pointer to type&quot; rather than an
+ &quot;array of type&quot; (requires partial
+ specialization). Note that if you are using value_type as
+ a stored value then this will result in storing a &quot;constant
+ pointer to an array&quot; rather than the array itself.
+ This may or may not be a good thing depending upon what
+ you actually need (in other words take care!).</li>
+ <li>If T is a small built in type or a pointer, then <code>param_type</code>
+ is defined as <code>T const</code>, instead of <code>T
+ const&amp;</code>. This can improve the ability of the
+ compiler to optimize loops in the body of the function if
+ they depend upon the passed parameter, the semantics of
+ the passed parameter is otherwise unchanged (requires
+ partial specialization).</li>
+</ol>
+
+<p>&nbsp;</p>
+
+<h3>Copy constructibility</h3>
+
+<p>The following table defines which call_traits types can always
+be copy-constructed from which other types, those entries marked
+with a '?' are true only if and only if T is copy constructible:</p>
+
+<table border="0" cellpadding="7" cellspacing="1" width="766">
+ <tr>
+ <td valign="top" width="17%">&nbsp;</td>
+ <td valign="top" colspan="5" width="85%"
+ bgcolor="#008080"><p align="center">To:</p>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" width="17%" bgcolor="#008080">From:</td>
+ <td valign="top" width="17%" bgcolor="#C0C0C0"><p
+ align="center">T</p>
+ </td>
+ <td valign="top" width="17%" bgcolor="#C0C0C0"><p
+ align="center">value_type</p>
+ </td>
+ <td valign="top" width="17%" bgcolor="#C0C0C0"><p
+ align="center">reference</p>
+ </td>
+ <td valign="top" width="17%" bgcolor="#C0C0C0"><p
+ align="center">const_reference</p>
+ </td>
+ <td valign="top" width="17%" bgcolor="#C0C0C0"><p
+ align="center">param_type</p>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" width="17%" bgcolor="#C0C0C0">T</td>
+ <td valign="top" width="17%"><p align="center">?</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">?</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">Y</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">Y</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">Y</p>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" width="17%" bgcolor="#C0C0C0">value_type</td>
+ <td valign="top" width="17%"><p align="center">?</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">?</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">N</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">N</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">Y</p>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" width="17%" bgcolor="#C0C0C0">reference</td>
+ <td valign="top" width="17%"><p align="center">?</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">?</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">Y</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">Y</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">Y</p>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" width="17%" bgcolor="#C0C0C0">const_reference</td>
+ <td valign="top" width="17%"><p align="center">?</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">N</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">N</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">Y</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">Y</p>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" width="17%" bgcolor="#C0C0C0">param_type</td>
+ <td valign="top" width="17%"><p align="center">?</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">?</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">N</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">N</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">Y</p>
+ </td>
+ </tr>
+</table>
+
+<p>&nbsp;</p>
+
+<p>If T is an assignable type the following assignments are
+possible:</p>
+
+<table border="0" cellpadding="7" cellspacing="1" width="766">
+ <tr>
+ <td valign="top" width="17%">&nbsp;</td>
+ <td valign="top" colspan="5" width="85%"
+ bgcolor="#008080"><p align="center">To:</p>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" width="17%" bgcolor="#008080">From:</td>
+ <td valign="top" width="17%" bgcolor="#C0C0C0"><p
+ align="center">T</p>
+ </td>
+ <td valign="top" width="17%" bgcolor="#C0C0C0"><p
+ align="center">value_type</p>
+ </td>
+ <td valign="top" width="17%" bgcolor="#C0C0C0"><p
+ align="center">reference</p>
+ </td>
+ <td valign="top" width="17%" bgcolor="#C0C0C0"><p
+ align="center">const_reference</p>
+ </td>
+ <td valign="top" width="17%" bgcolor="#C0C0C0"><p
+ align="center">param_type</p>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" width="17%" bgcolor="#C0C0C0">T</td>
+ <td valign="top" width="17%"><p align="center">Y</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">Y</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">-</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">-</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">-</p>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" width="17%" bgcolor="#C0C0C0">value_type</td>
+ <td valign="top" width="17%"><p align="center">Y</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">Y</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">-</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">-</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">-</p>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" width="17%" bgcolor="#C0C0C0">reference</td>
+ <td valign="top" width="17%"><p align="center">Y</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">Y</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">-</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">-</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">-</p>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" width="17%" bgcolor="#C0C0C0">const_reference</td>
+ <td valign="top" width="17%"><p align="center">Y</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">Y</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">-</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">-</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">-</p>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" width="17%" bgcolor="#C0C0C0">param_type</td>
+ <td valign="top" width="17%"><p align="center">Y</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">Y</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">-</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">-</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">-</p>
+ </td>
+ </tr>
+</table>
+
+<p>&nbsp;</p>
+
+<h3><a name="examples"></a>Examples</h3>
+
+<p>The following table shows the effect that call_traits has on
+various types, the table assumes that the compiler supports
+partial specialization: if it doesn't then all types behave in
+the same way as the entry for &quot;myclass&quot;, and
+call_traits can not be used with reference or array types.</p>
+
+<table border="0" cellpadding="7" cellspacing="1" width="766">
+ <tr>
+ <td valign="top" width="17%">&nbsp;</td>
+ <td valign="top" colspan="5" width="85%"
+ bgcolor="#008080"><p align="center">Call_traits type:</p>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" width="17%" bgcolor="#008080"><p
+ align="center">Original type T</p>
+ </td>
+ <td valign="top" width="17%" bgcolor="#C0C0C0"><p
+ align="center">value_type</p>
+ </td>
+ <td valign="top" width="17%" bgcolor="#C0C0C0"><p
+ align="center">reference</p>
+ </td>
+ <td valign="top" width="17%" bgcolor="#C0C0C0"><p
+ align="center">const_reference</p>
+ </td>
+ <td valign="top" width="17%" bgcolor="#C0C0C0"><p
+ align="center">param_type</p>
+ </td>
+ <td valign="top" width="17%" bgcolor="#C0C0C0"><p
+ align="center">Applies to:</p>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" width="17%" bgcolor="#C0C0C0"><p
+ align="center">myclass</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">myclass</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">myclass&amp;</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">const
+ myclass&amp;</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">myclass
+ const&amp;</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">All user
+ defined types.</p>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" width="17%" bgcolor="#C0C0C0"><p
+ align="center">int</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">int</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">int&amp;</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">const
+ int&amp;</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">int const</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">All small
+ built-in types.</p>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" width="17%" bgcolor="#C0C0C0"><p
+ align="center">int*</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">int*</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">int*&amp;</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">int*const&amp;</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">int* const</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">All
+ pointer types.</p>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" width="17%" bgcolor="#C0C0C0"><p
+ align="center">int&amp;</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">int&amp;</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">int&amp;</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">const
+ int&amp;</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">int&amp;</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">All
+ reference types.</p>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" width="17%" bgcolor="#C0C0C0"><p
+ align="center">const int&amp;</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">const
+ int&amp;</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">const
+ int&amp;</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">const
+ int&amp;</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">const
+ int&amp;</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">All
+ constant-references.</p>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" width="17%" bgcolor="#C0C0C0"><p
+ align="center">int[3]</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">const int*</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">int(&amp;)[3]</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">const int(&amp;)[3]</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">const int*
+ const</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">All array
+ types.</p>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" width="17%" bgcolor="#C0C0C0"><p
+ align="center">const int[3]</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">const int*</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">const int(&amp;)[3]</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">const int(&amp;)[3]</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">const int*
+ const</p>
+ </td>
+ <td valign="top" width="17%"><p align="center">All
+ constant-array types.</p>
+ </td>
+ </tr>
+</table>
+
+<p>&nbsp;</p>
+
+<h4>Example 1:</h4>
+
+<p>The following class is a trivial class that stores some type T
+by value (see the <a href="test/call_traits_test.cpp">call_traits_test.cpp</a>
+file), the aim is to illustrate how each of the available
+call_traits typedefs may be used:</p>
+
+<pre>template &lt;class T&gt;
+struct contained
+{
+ // define our typedefs first, arrays are stored by value
+ // so value_type is not the same as result_type:
+ typedef typename boost::call_traits&lt;T&gt;::param_type param_type;
+ typedef typename boost::call_traits&lt;T&gt;::reference reference;
+ typedef typename boost::call_traits&lt;T&gt;::const_reference const_reference;
+ typedef T value_type;
+ typedef typename boost::call_traits&lt;T&gt;::value_type result_type;
+
+ // stored value:
+ value_type v_;
+
+ // constructors:
+ contained() {}
+ contained(param_type p) : v_(p){}
+ // return byval:
+ result_type value() { return v_; }
+ // return by_ref:
+ reference get() { return v_; }
+ const_reference const_get()const { return v_; }
+ // pass value:
+ void call(param_type p){}
+
+};</pre>
+
+<h4><a name="refs"></a>Example 2 (the reference to reference
+problem):</h4>
+
+<p>Consider the definition of std::binder1st:</p>
+
+<pre>template &lt;class Operation&gt;
+class binder1st :
+ public unary_function&lt;typename Operation::second_argument_type, typename Operation::result_type&gt;
+{
+protected:
+ Operation op;
+ typename Operation::first_argument_type value;
+public:
+ binder1st(const Operation&amp; x, const typename Operation::first_argument_type&amp; y);
+ typename Operation::result_type operator()(const typename Operation::second_argument_type&amp; x) const;
+}; </pre>
+
+<p>Now consider what happens in the relatively common case that
+the functor takes its second argument as a reference, that
+implies that <code>Operation::second_argument_type</code> is a
+reference type, <code>operator()</code> will now end up taking a
+reference to a reference as an argument, and that is not
+currently legal. The solution here is to modify <code>operator()</code>
+to use call_traits:</p>
+
+<pre>typename Operation::result_type operator()(typename call_traits&lt;typename Operation::second_argument_type&gt;::param_type x) const;</pre>
+
+<p>Now in the case that <code>Operation::second_argument_type</code>
+is a reference type, the argument is passed as a reference, and
+the no &quot;reference to reference&quot; occurs.</p>
+
+<h4><a name="ex3"></a>Example 3 (the make_pair problem):</h4>
+
+<p>If we pass the name of an array as one (or both) arguments to <code>std::make_pair</code>,
+then template argument deduction deduces the passed parameter as
+&quot;const reference to array of T&quot;, this also applies to
+string literals (which are really array literals). Consequently
+instead of returning a pair of pointers, it tries to return a
+pair of arrays, and since an array type is not copy-constructible
+the code fails to compile. One solution is to explicitly cast the
+arguments to make_pair to pointers, but call_traits provides a
+better (i.e. automatic) solution (and one that works safely even
+in generic code where the cast might do the wrong thing):</p>
+
+<pre>template &lt;class T1, class T2&gt;
+std::pair&lt;
+ typename boost::call_traits&lt;T1&gt;::value_type,
+ typename boost::call_traits&lt;T2&gt;::value_type&gt;
+ make_pair(const T1&amp; t1, const T2&amp; t2)
+{
+ return std::pair&lt;
+ typename boost::call_traits&lt;T1&gt;::value_type,
+ typename boost::call_traits&lt;T2&gt;::value_type&gt;(t1, t2);
+}</pre>
+
+<p>Here, the deduced argument types will be automatically
+degraded to pointers if the deduced types are arrays, similar
+situations occur in the standard binders and adapters: in
+principle in any function that &quot;wraps&quot; a temporary
+whose type is deduced. Note that the function arguments to
+make_pair are not expressed in terms of call_traits: doing so
+would prevent template argument deduction from functioning.</p>
+
+<h4><a name="ex4"></a>Example 4 (optimising fill):</h4>
+
+<p>The call_traits template will &quot;optimize&quot; the passing
+of a small built-in type as a function parameter, this mainly has
+an effect when the parameter is used within a loop body. In the
+following example (see <a
+href="../type_traits/examples/fill_example.cpp">fill_example.cpp</a>),
+a version of std::fill is optimized in two ways: if the type
+passed is a single byte built-in type then std::memset is used to
+effect the fill, otherwise a conventional C++ implemention is
+used, but with the passed parameter &quot;optimized&quot; using
+call_traits:</p>
+
+<pre>namespace detail{
+
+template &lt;bool opt&gt;
+struct filler
+{
+ template &lt;typename I, typename T&gt;
+ static void do_fill(I first, I last, typename boost::call_traits&lt;T&gt;::param_type val)
+ {
+ while(first != last)
+ {
+ *first = val;
+ ++first;
+ }
+ }
+};
+
+template &lt;&gt;
+struct filler&lt;true&gt;
+{
+ template &lt;typename I, typename T&gt;
+ static void do_fill(I first, I last, T val)
+ {
+ memset(first, val, last-first);
+ }
+};
+
+}
+
+template &lt;class I, class T&gt;
+inline void fill(I first, I last, const T&amp; val)
+{
+ enum{ can_opt = boost::is_pointer&lt;I&gt;::value
+ &amp;&amp; boost::is_arithmetic&lt;T&gt;::value
+ &amp;&amp; (sizeof(T) == 1) };
+ typedef detail::filler&lt;can_opt&gt; filler_t;
+ filler_t::template do_fill&lt;I,T&gt;(first, last, val);
+}</pre>
+
+<p>Footnote: the reason that this is &quot;optimal&quot; for
+small built-in types is that with the value passed as &quot;T
+const&quot; instead of &quot;const T&amp;&quot; the compiler is
+able to tell both that the value is constant and that it is free
+of aliases. With this information the compiler is able to cache
+the passed value in a register, unroll the loop, or use
+explicitly parallel instructions: if any of these are supported.
+Exactly how much mileage you will get from this depends upon your
+compiler - we could really use some accurate benchmarking
+software as part of boost for cases like this.</p>
+
+<p>Note that the function arguments to fill are not expressed in
+terms of call_traits: doing so would prevent template argument
+deduction from functioning. Instead fill acts as a &quot;thin
+wrapper&quot; that is there to perform template argument
+deduction, the compiler will optimise away the call to fill all
+together, replacing it with the call to filler&lt;&gt;::do_fill,
+which does use call_traits.</p>
+
+<h3>Rationale</h3>
+
+<p>The following notes are intended to briefly describe the
+rational behind choices made in call_traits.</p>
+
+<p>All user-defined types follow &quot;existing practice&quot;
+and need no comment.</p>
+
+<p>Small built-in types (what the standard calls fundamental
+types [3.9.1]) differ from existing practice only in the <i>param_type</i>
+typedef. In this case passing &quot;T const&quot; is compatible
+with existing practice, but may improve performance in some cases
+(see <a href="#ex4">Example 4</a>), in any case this should never
+be any worse than existing practice.</p>
+
+<p>Pointers follow the same rational as small built-in types.</p>
+
+<p>For reference types the rational follows <a href="#refs">Example
+2</a> - references to references are not allowed, so the
+call_traits members must be defined such that these problems do
+not occur. There is a proposal to modify the language such that
+&quot;a reference to a reference is a reference&quot; (issue #106,
+submitted by Bjarne Stroustrup), call_traits&lt;T&gt;::value_type
+and call_traits&lt;T&gt;::param_type both provide the same effect
+as that proposal, without the need for a language change (in
+other words it's a workaround).</p>
+
+<p>For array types, a function that takes an array as an argument
+will degrade the array type to a pointer type: this means that
+the type of the actual parameter is different from its declared
+type, something that can cause endless problems in template code
+that relies on the declared type of a parameter. For example:</p>
+
+<pre>template &lt;class T&gt;
+struct A
+{
+ void foo(T t);
+};</pre>
+
+<p><font face="Times New Roman">In this case if we instantiate
+A&lt;int[2]&gt; then the declared type of the parameter passed to
+member function foo is int[2], but it's actual type is const int*,
+if we try to use the type T within the function body, then there
+is a strong likelyhood that our code will not compile:</font></p>
+
+<pre>template &lt;class T&gt;
+void A&lt;T&gt;::foo(T t)
+{
+ T dup(t); // doesn't compile for case that T is an array.
+}</pre>
+
+<p>By using call_traits the degradation from array to pointer is
+explicit, and the type of the parameter is the same as it's
+declared type:</p>
+
+<pre>template &lt;class T&gt;
+struct A
+{
+ void foo(typename call_traits&lt;T&gt;::value_type t);
+};
+
+template &lt;class T&gt;
+void A&lt;T&gt;::foo(typename call_traits&lt;T&gt;::value_type t)
+{
+ typename call_traits&lt;T&gt;::value_type dup(t); // OK even if T is an array type.
+}</pre>
+
+<p>For value_type (return by value), again only a pointer may be
+returned, not a copy of the whole array, and again call_traits
+makes the degradation explicit. The value_type member is useful
+whenever an array must be explicitly degraded to a pointer - <a
+href="#ex3">Example 3</a> provides the test case (Footnote: the
+array specialisation for call_traits is the least well understood
+of all the call_traits specialisations, if the given semantics
+cause specific problems for you, or don't solve a particular
+array-related problem, then I would be interested to hear about
+it. Most people though will probably never need to use this
+specialisation).</p>
+
+<hr>
+
+<p>Revised 01 September 2000</p>
+
+ <p>
+ Copyright 2000 Steve Cleary, Beman Dawes, Howard
+ Hinnant and John Maddock. <br/>
+ Use, modification and distribution are subject to the
+ Boost Software License, Version 1.0.
+ (See accompanying file LICENSE_1_0.txt
+ or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+ http://www.boost.org/LICENSE_1_0.txt
+ </a>).
+ </p>
+</body>
+</html>
+
diff --git a/src/boost/libs/utility/checked_delete.html b/src/boost/libs/utility/checked_delete.html
new file mode 100644
index 000000000..1b9325615
--- /dev/null
+++ b/src/boost/libs/utility/checked_delete.html
@@ -0,0 +1,15 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<meta http-equiv=refresh content="0; URL=../core/doc/html/core/checked_delete.html">
+<title>Automatic redirection</title>
+</head>
+<body>
+Automatic redirection failed, please go to
+<a href="../core/doc/html/core/checked_delete.html">checked_delete.html</a>.&nbsp;<hr>
+<p>© Copyright Beman Dawes, 2001</p>
+<p>Distributed under the Boost Software License, Version 1.0. (See accompanying
+file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy
+at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</p>
+</body>
+</html>
diff --git a/src/boost/libs/utility/compressed_pair.htm b/src/boost/libs/utility/compressed_pair.htm
new file mode 100644
index 000000000..0b99bf7ac
--- /dev/null
+++ b/src/boost/libs/utility/compressed_pair.htm
@@ -0,0 +1,16 @@
+
+<!--
+Copyright 2014 Daniel James.
+Distributed under the Boost Software License, Version 1.0. (See accompanying
+file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+-->
+
+<html>
+<head>
+ <meta http-equiv="refresh" content="0; URL=doc/html/compressed_pair.html">
+</head>
+<body>
+Automatic redirection failed, please go to
+<a href="doc/html/compressed_pair.html">doc/html/compressed_pair.html</a>
+</body>
+</html>
diff --git a/src/boost/libs/utility/enable_if.html b/src/boost/libs/utility/enable_if.html
new file mode 100644
index 000000000..0cd1a985a
--- /dev/null
+++ b/src/boost/libs/utility/enable_if.html
@@ -0,0 +1,15 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<meta http-equiv=refresh content="0; URL=../core/doc/html/core/enable_if.html">
+<title>Automatic redirection</title>
+</head>
+<body>
+Automatic redirection failed, please go to
+<a href="../core/doc/html/core/enable_if.html">enable_if.html</a>.&nbsp;<hr>
+<p>© Copyright Beman Dawes, 2001</p>
+<p>Distributed under the Boost Software License, Version 1.0. (See accompanying
+file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy
+at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</p>
+</body>
+</html>
diff --git a/src/boost/libs/utility/identity_type/index.html b/src/boost/libs/utility/identity_type/index.html
new file mode 100644
index 000000000..00b33623c
--- /dev/null
+++ b/src/boost/libs/utility/identity_type/index.html
@@ -0,0 +1,15 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+ <head>
+ <meta http-equiv="refresh" content="0; URL=doc/html/index.html">
+ </head>
+ <body>
+ Automatic redirection failed, click this
+ <a href="doc/html/index.html">link</a> &nbsp;<hr>
+ <p>© Copyright Lorenzo Caminiti, 2009-2012</p>
+ <p>Distributed under the Boost Software License, Version 1.0 (see
+ accompanying file <a href="../../../LICENSE_1_0.txt">
+ LICENSE_1_0.txt</a> or a copy at
+ <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</p>
+ </body>
+</html>
diff --git a/src/boost/libs/utility/identity_type/test/Jamfile.v2 b/src/boost/libs/utility/identity_type/test/Jamfile.v2
new file mode 100644
index 000000000..5cb50366d
--- /dev/null
+++ b/src/boost/libs/utility/identity_type/test/Jamfile.v2
@@ -0,0 +1,16 @@
+
+# Copyright (C) 2009-2012 Lorenzo Caminiti
+# Distributed under the Boost Software License, Version 1.0
+# (see accompanying file LICENSE_1_0.txt or a copy at
+# http://www.boost.org/LICENSE_1_0.txt)
+# Home at http://www.boost.org/libs/utility/identity_type
+
+import testing ;
+
+compile-fail var_error.cpp ;
+run var.cpp ;
+run template.cpp ;
+run abstract.cpp ;
+run noncopyable.cpp ;
+run paren.cpp ;
+
diff --git a/src/boost/libs/utility/identity_type/test/abstract.cpp b/src/boost/libs/utility/identity_type/test/abstract.cpp
new file mode 100644
index 000000000..39b10c35a
--- /dev/null
+++ b/src/boost/libs/utility/identity_type/test/abstract.cpp
@@ -0,0 +1,35 @@
+
+// Copyright (C) 2009-2012 Lorenzo Caminiti
+// Distributed under the Boost Software License, Version 1.0
+// (see accompanying file LICENSE_1_0.txt or a copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// Home at http://www.boost.org/libs/utility/identity_type
+
+#include <boost/utility/identity_type.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/add_reference.hpp>
+#include <boost/type_traits/remove_reference.hpp>
+
+//[abstract
+#define TMP_ASSERT(metafunction) \
+ BOOST_STATIC_ASSERT(metafunction::value)
+
+template<typename T, bool b>
+struct abstract {
+ static const bool value = b;
+ virtual void f(T const& x) = 0; // Pure virtual function.
+};
+
+TMP_ASSERT(
+ boost::remove_reference< // Add and remove
+ BOOST_IDENTITY_TYPE(( // reference for
+ boost::add_reference< // abstract type.
+ abstract<int, true>
+ >::type
+ ))
+ >::type
+);
+//]
+
+int main() { return 0; }
+
diff --git a/src/boost/libs/utility/identity_type/test/noncopyable.cpp b/src/boost/libs/utility/identity_type/test/noncopyable.cpp
new file mode 100644
index 000000000..2819e6850
--- /dev/null
+++ b/src/boost/libs/utility/identity_type/test/noncopyable.cpp
@@ -0,0 +1,25 @@
+
+// Copyright (C) 2009-2012 Lorenzo Caminiti
+// Distributed under the Boost Software License, Version 1.0
+// (see accompanying file LICENSE_1_0.txt or a copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// Home at http://www.boost.org/libs/utility/identity_type
+
+#include <boost/utility/identity_type.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/noncopyable.hpp>
+
+//[noncopyable
+#define TMP_ASSERT(metafunction) \
+ BOOST_STATIC_ASSERT(metafunction::value)
+
+template<typename T, T init>
+struct noncopyable : boost::noncopyable {
+ static const T value = init;
+};
+
+TMP_ASSERT(BOOST_IDENTITY_TYPE((noncopyable<bool, true>)));
+//]
+
+int main() { return 0; }
+
diff --git a/src/boost/libs/utility/identity_type/test/paren.cpp b/src/boost/libs/utility/identity_type/test/paren.cpp
new file mode 100644
index 000000000..51b355fe9
--- /dev/null
+++ b/src/boost/libs/utility/identity_type/test/paren.cpp
@@ -0,0 +1,35 @@
+
+// Copyright (C) 2009-2012 Lorenzo Caminiti
+// Distributed under the Boost Software License, Version 1.0
+// (see accompanying file LICENSE_1_0.txt or a copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// Home at http://www.boost.org/libs/utility/identity_type
+
+#include <boost/utility/identity_type.hpp>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_const.hpp>
+#include <map>
+
+//[paren
+#define TMP_ASSERT_PAREN(parenthesized_metafunction) \
+ /* use `BOOST_IDENTITY_TYPE` in macro definition instead of invocation */ \
+ BOOST_STATIC_ASSERT(BOOST_IDENTITY_TYPE(parenthesized_metafunction)::value)
+
+#define TMP_ASSERT(metafunction) \
+ BOOST_STATIC_ASSERT(metafunction::value)
+
+// Specify only extra parenthesis `((...))`.
+TMP_ASSERT_PAREN((boost::is_const<std::map<int, char> const>));
+
+// Specify both the extra parenthesis `((...))` and `BOOST_IDENTITY_TYPE` macro.
+TMP_ASSERT(BOOST_IDENTITY_TYPE((boost::is_const<std::map<int, char> const>)));
+//]
+
+//[paren_always
+TMP_ASSERT_PAREN((boost::is_const<int const>)); // Always extra `((...))`.
+
+TMP_ASSERT(boost::is_const<int const>); // No extra `((...))` and no macro.
+//]
+
+int main() { return 0; }
+
diff --git a/src/boost/libs/utility/identity_type/test/template.cpp b/src/boost/libs/utility/identity_type/test/template.cpp
new file mode 100644
index 000000000..dfc109795
--- /dev/null
+++ b/src/boost/libs/utility/identity_type/test/template.cpp
@@ -0,0 +1,48 @@
+
+// Copyright (C) 2009-2012 Lorenzo Caminiti
+// Distributed under the Boost Software License, Version 1.0
+// (see accompanying file LICENSE_1_0.txt or a copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// Home at http://www.boost.org/libs/utility/identity_type
+
+#include <boost/utility/identity_type.hpp>
+#include <map>
+#include <iostream>
+
+//[template_f_decl
+#define ARG(type, n) type arg ## n
+
+template<typename T>
+void f( // Prefix macro with `typename` in templates.
+ ARG(typename BOOST_IDENTITY_TYPE((std::map<int, T>)), 1)
+) {
+ std::cout << arg1[0] << std::endl;
+}
+//]
+
+//[template_g_decl
+template<typename T>
+void g(
+ std::map<int, T> arg1
+) {
+ std::cout << arg1[0] << std::endl;
+}
+//]
+
+int main() {
+ //[template_f_call
+ std::map<int, char> a;
+ a[0] = 'a';
+
+ f<char>(a); // OK...
+ // f(a); // ... but error.
+ //]
+
+ //[template_g_call
+ g<char>(a); // OK...
+ g(a); // ... and also OK.
+ //]
+
+ return 0;
+}
+
diff --git a/src/boost/libs/utility/identity_type/test/var.cpp b/src/boost/libs/utility/identity_type/test/var.cpp
new file mode 100644
index 000000000..9ed165d71
--- /dev/null
+++ b/src/boost/libs/utility/identity_type/test/var.cpp
@@ -0,0 +1,26 @@
+
+// Copyright (C) 2009-2012 Lorenzo Caminiti
+// Distributed under the Boost Software License, Version 1.0
+// (see accompanying file LICENSE_1_0.txt or a copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// Home at http://www.boost.org/libs/utility/identity_type
+
+#include <map>
+
+#define VAR(type, n) type var ## n
+
+VAR(int, 1); // OK.
+
+//[var_typedef
+typedef std::map<int, char> map_type;
+VAR(map_type, 3); // OK.
+//]
+
+//[var_ok
+#include <boost/utility/identity_type.hpp>
+
+VAR(BOOST_IDENTITY_TYPE((std::map<int, char>)), 4); // OK.
+//]
+
+int main() { return 0; }
+
diff --git a/src/boost/libs/utility/identity_type/test/var_error.cpp b/src/boost/libs/utility/identity_type/test/var_error.cpp
new file mode 100644
index 000000000..efb9743f5
--- /dev/null
+++ b/src/boost/libs/utility/identity_type/test/var_error.cpp
@@ -0,0 +1,18 @@
+
+// Copyright (C) 2009-2012 Lorenzo Caminiti
+// Distributed under the Boost Software License, Version 1.0
+// (see accompanying file LICENSE_1_0.txt or a copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+// Home at http://www.boost.org/libs/utility/identity_type
+
+#include <map>
+
+//[var_error
+#define VAR(type, n) type var ## n
+
+VAR(int, 1); // OK.
+VAR(std::map<int, char>, 2); // Error.
+//]
+
+int main() { return 0; }
+
diff --git a/src/boost/libs/utility/in_place_factories.html b/src/boost/libs/utility/in_place_factories.html
new file mode 100644
index 000000000..8eb7ea8d4
--- /dev/null
+++ b/src/boost/libs/utility/in_place_factories.html
@@ -0,0 +1,296 @@
+<!DOCTYPE HTML PUBLIC "-//SoftQuad Software//DTD HoTMetaL PRO 5.0::19981217::extensions to HTML 4.0//EN" "hmpro5.dtd">
+
+<HTML>
+
+<HEAD>
+<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
+<TITLE>In_place_factory Documentation</TITLE>
+</HEAD>
+
+<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#800080">
+<H2 align="left"><IMG SRC="../../boost.png" WIDTH="276" HEIGHT="86"></H2>
+
+<blockquote>
+ <blockquote>
+ <blockquote>
+ <blockquote>
+ <blockquote>
+ <blockquote>
+<H2 align="left">Header &lt;<A
+HREF="../../boost/utility/in_place_factory.hpp">boost/utility/in_place_factory.hpp</A>&gt; </H2>
+
+<H2 align="left">Header &lt;<A
+HREF="../../boost/utility/typed_in_place_factory.hpp">boost/utility/typed_in_place_factory.hpp</A>&gt; </H2>
+
+ </blockquote>
+ </blockquote>
+ </blockquote>
+ </blockquote>
+ </blockquote>
+</blockquote>
+<p>&nbsp;</p>
+
+<H2>Contents</H2>
+<DL CLASS="page-index">
+ <DT><A HREF="#mot">Motivation</A></DT>
+ <DT><A HREF="#framework">Framework</A></DT>
+ <DT><A HREF="#specification">Specification</A></DT>
+ <DT><A HREF="#container-usage">Container-side Usage</A></DT>
+ <DT><A HREF="#user-usage">User-side Usage</A></DT>
+</DL>
+
+<HR>
+
+<H2><A NAME="mot"></A>Motivation</H2>
+
+<p>Suppose we have a class</p>
+<pre>struct X
+{
+ X ( int, std::string ) ;
+} ;</pre>
+<p>And a container for it which supports an empty state (that is, which can contain zero objects):</p>
+<pre>struct C
+{
+ C() : contained_(0) {}
+ ~C() { delete contained_ ; }
+ X* contained_ ;
+} ;</pre>
+<p>A container designed to support an empty state typically doesn't require the contained type to be DefaultConstructible,
+but it typically requires it to be CopyConstructible as a mechanism to
+initialize the object to store:</p>
+<pre>struct C
+{
+ C() : contained_(0) {}
+ C ( X const& v ) : contained_ ( new X(v) ) {}
+ ~C() { delete contained_ ; }
+ X* contained_ ;
+} ;</pre>
+<p>There is a subtle problem with this: since the mechanism used to initialize the stored object is copy construction,
+there must exist a previously constructed source object to copy from. This
+object is likely to be temporary and serve no purpose besides being the source</p>
+<pre>void foo()
+{
+ // Temporary object created.
+ C c( X(123,"hello") ) ;
+}
+</pre>
+<p>A solution to this problem is to support direct construction of the contained
+object right in the container's storage.<br>
+In this scheme, the user supplies the arguments for the X constructor
+directly to the container:</p>
+<pre>struct C
+{
+ C() : contained_(0) {}
+ C ( X const& v ) : contained_ ( new X(v) ) {}
+ C ( int a0, std::string a1 ) : contained_ ( new X(a0,a1) ) {}
+ ~C() { delete contained_ ; }
+ X* contained_ ;
+} ;</pre>
+<pre>void foo()
+{
+ // Wrapped object constructed in-place
+ // No temporary created.
+ C c(123,"hello") ;
+}
+</pre>
+<p>Clearly, this solution doesn't scale well since the container must duplicate all the constructor overloads from the contained type
+(at least all those which are to be supported directly in the container).</p>
+
+<H2><A NAME="framework"></A>Framework</H2>
+<p>
+This library proposes a framework to allow some containers to directly contruct contained objects in-place without requiring
+the entire set of constructor overloads from the contained type. It also allows the container to remove the CopyConstuctible
+requirement from the contained type since objects can be directly constructed in-place without need of a copy.<br>
+The only requirement on the container is that it must provide proper storage (that is, correctly aligned and sized).
+Naturally, the container will typically support uninitialized storage to avoid the in-place construction to override
+a fully-constructed object (as this would defeat the purpose of in-place construction)
+</p>
+<p>For this purpose, the framework provides two families of classes collectively called: InPlaceFactories and TypedInPlaceFactories.<br>
+Essentially, these classes hold a sequence of actual parameters and a method to contruct an object in place using these parameters.
+Each member of the family differs only in the number (and type) of the parameter list. The first family
+takes the type of the object to construct directly in method provided for that
+purpose, whereas the second family incorporates that type in the factory class
+itself..</p>
+<p>From the container POV, using the framework amounts to calling the factory's method to contruct the object in place.
+From the user POV, it amounts to creating the right factory object to hold the parameters and pass it to the container.<br>
+The following simplified example shows the basic idea. A complete example follows the formal specification of the framework:</p>
+<pre>struct C
+{
+ template&lt;class InPlaceFactory&gt;
+ C ( InPlaceFactory const& aFactory )
+ :
+ contained_ ( uninitialized_storage() )
+ {
+ aFactory.template apply&lt;X&gt;(contained_);
+ }
+
+ ~C()
+ {
+ contained_ -> X::~X();
+ delete[] contained_ ;
+ }
+
+ char* uninitialized_storage() { return new char[sizeof(X)] ; }
+
+ char* contained_ ;
+} ;
+
+void foo()
+{
+ C c( in_place(123,"hello") ) ;
+}
+</pre>
+
+<HR>
+
+<H2><A NAME="specification">Specification</A></H2>
+
+<p>The following is the first member of the family of 'in_place_factory' classes, along with its corresponding helper template function.
+The rest of the family varies only in the number and type of template (and constructor) parameters.</p>
+<PRE>namespace boost {
+
+struct in_place_factory_base {} ;
+
+template&lt;class A0&gt;
+class in_place_factory : public in_place_factory_base
+{
+ public:</PRE>
+
+<PRE> in_place_factory ( A0 const& a0 ) : m_a0(a0) {}
+
+ template&lt; class T &gt;
+ void apply ( void* address ) const
+ {
+ new (address) T(m_a0);
+ }
+
+ private:</PRE>
+
+<PRE> A0 const& m_a0 ;
+} ;
+
+template&lt;class A0&gt;
+in_place_factory&lt;A0&gt; in_place ( A0 const& a0 )
+{
+ return in_place_factory&lt;A0&gt;(a0);
+}
+</PRE>
+
+<p>Similarly, the following is the first member of the family of 'typed_in_place_factory' classes, along with its corresponding
+helper template function. The rest of the family varies only in the number and type of template (and constructor) parameters.</p>
+<PRE>namespace boost {
+
+struct typed_in_place_factory_base {} ;
+
+template&lt;class T, class A0&gt;
+class typed_in_place_factory : public typed_in_place_factory_base
+{
+ public:</PRE>
+
+<PRE> typed_in_place_factory ( A0 const& a0 ) : m_a0(a0) {}
+
+ void apply ( void* address ) const
+ {
+ new (address) T(m_a0);
+ }
+
+ private:</PRE>
+
+<PRE> A0 const& m_a0 ;
+} ;
+
+template&lt;class T, class A0&gt;
+typed_in_place_factory&lt;A0&gt; in_place ( A0 const& a0 )
+{
+ return typed_in_place_factory&lt;T,A0&gt;(a0);
+}</PRE>
+
+<PRE>}
+</PRE>
+
+<p>As you can see, the 'in_place_factory' and 'typed_in_place_factory' template classes varies only in the way they specify
+the target type: in the first family, the type is given as a template argument to the apply member function while in the
+second it is given directly as part of the factory class.<br>
+When the container holds a unique non-polymorphic type (such as the case of Boost.Optional), it knows the exact dynamic-type
+of the contained object and can pass it to the apply() method of a (non-typed) factory.
+In this case, end users can use an 'in_place_factory' instance which can be constructed without the type of the object to construct.<br>
+However, if the container holds heterogeneous or polymorphic objects (such as the case of Boost.Variant), the dynamic-type
+of the object to be constructed must be known by the factory itslef. In this case, end users must use a 'typed_in_place_factory'
+instead.</p>
+
+<HR>
+
+<h2><A NAME="container-usage">Container-side Usage</a></h2>
+
+<p>As shown in the introductory simplified example, the container class must
+contain methods that accept an instance of
+these factories and pass the object's storage to the factory's apply method.<br>
+However, the type of the factory class cannot be completly specified in the container class because that would
+defeat the whole purpose of the factories which is to allow the container to accept a variadic argument list
+for the constructor of its contained object.<br>
+The correct function overload must be based on the only distinctive and common
+characteristic of all the classes in each family, the base class.<br>
+Depending on the container class, you can use 'enable_if' to generate the right overload, or use the following
+dispatch technique (used in the Boost.Optional class):
+</p>
+<pre>struct C
+{
+ C() : contained_(0) {}
+ C ( X const& v ) : contained_ ( new X(v) ) {}
+
+ template&lt;class Expr&gt
+ C ( Expr const& expr )
+ :
+ contained_ ( uninitialized_storage() )
+ {
+ construct(expr,&expr)
+ }
+
+ ~C() { delete contained_ ; }
+
+ template&lt;class InPlaceFactory&gt;
+ void construct ( InPlaceFactory const& aFactory, boost::in_place_factory_base* )
+ {
+ aFactory.template apply&lt;X&gt;(contained_);
+ }
+
+ template&lt;class TypedInPlaceFactory&gt;
+ void construct ( TypedInPlaceFactory const& aFactory, boost::typed_in_place_factory_base* )
+ {
+ aFactory.apply(contained_);
+ }
+
+ X* uninitialized_storage() { return static_cast&lt;X*&gt;(new char[sizeof(X)]) ; }
+
+ X* contained_ ;
+} ;
+</pre>
+
+<hr>
+
+<h2><A NAME="user-usage">User-side Usage</a></h2>
+
+<p>End users pass to the container an instance of a factory object holding the actual parameters needed to construct the
+contained object directly within the container. For this, the helper template function 'in_place' is used.<br>
+The call 'in_place(a0,a1,a2,...,an)' constructs a (non-typed) 'in_place_factory' instance with the given argument list.<br>
+The call 'in_place&lt;T&gt;(a0,a1,a2,...,an)' constructs a 'typed_in_place_factory' instance with the given argument list for the
+type 'T'.</p>
+<pre>void foo()
+{
+ C a( in_place(123,"hello") ) ; // in_place_factory passed
+ C b( in_place&lt;X&gt;(456,"world") ) ; // typed_in_place_factory passed
+}
+</pre>
+
+<P>Revised September 17, 2004</P>
+<p>© Copyright Fernando Luis Cacciola Carballal, 2004</p>
+<p> Use, modification, and distribution are subject to the Boost Software
+License, Version 1.0. (See accompanying file <a href="../../LICENSE_1_0.txt">
+LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt">
+www.boost.org/LICENSE_1_0.txt</a>)</p>
+<P>Developed by <A HREF="mailto:fernando_cacciola@hotmail.com">Fernando Cacciola</A>,
+the latest version of this file can be found at <A
+HREF="http://www.boost.org">www.boost.org</A>, and the boost
+<A HREF="http://www.boost.org/more/mailing_lists.htm#main">discussion lists</A></P>
+</BODY>
+</HTML>
diff --git a/src/boost/libs/utility/index.html b/src/boost/libs/utility/index.html
new file mode 100644
index 000000000..c2af44f9e
--- /dev/null
+++ b/src/boost/libs/utility/index.html
@@ -0,0 +1,50 @@
+<html>
+ <head>
+ <meta http-equiv="Content-Language" content="en-us">
+ <meta name="GENERATOR" content="Microsoft FrontPage 5.0">
+ <meta name="ProgId" content="FrontPage.Editor.Document">
+ <meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
+ <title>Boost Utility Library</title>
+ </head>
+ <body bgcolor="#FFFFFF">
+ <h1><IMG SRC="../../boost.png" WIDTH="276" HEIGHT="86" align="center">Boost
+ Utility Library</h1>
+ <p>The Boost Utility Library isn't really a single library at all. It is just a
+ collection for components too small to be called libraries in their own right.</p>
+ <p>But that doesn't mean there isn't useful stuff here. Take a look:</p>
+ <ul>
+ <li><a href="doc/html/base_from_member.html">base_from_member</a></li>
+ <li><a href="utility.htm#BOOST_BINARY">BOOST_BINARY</a></li>
+ <li><a href="call_traits.htm">call_traits</a></li>
+ <li><a href="doc/html/compressed_pair.html">compressed_pair</a></li>
+ <li><a href="in_place_factories.html">in_place_factory</a></li>
+ <li><a href="iterator_adaptors.htm">iterator_adaptors</a></li>
+ <li><a href="operators.htm">operators</a></li>
+ <li><a href="utility.htm#result_of">result_of</a></li>
+ <li><a href="throw_exception.html">throw_exception</a></li>
+ <li><a href="utility.htm">utility</a></li>
+ <li><a href="doc/html/string_ref.html">string_ref</a></li>
+ <li><a href="value_init.htm">value_init</a></li>
+ </ul>
+ <p>Over time useful stuff here has moved to more appropriate Boost libraries:</p>
+ <ul>
+ <li><a href="../core/doc/html/core/addressof.html">addressof</a> (moved to Boost.Core)</li>
+ <li><a href="../core/doc/html/core/checked_delete.html">checked_delete</a> (moved to Boost.Core)</li>
+ <li><a href="../type_traits/doc/html/boost_typetraits/reference/declval.html">declval</a> (moved to Boost.TypeTraits)</li>
+ <li><a href="../core/doc/html/core/enable_if.html">enable_if</a> (moved to Boost.Core)</li>
+ <li><a href="../iterator/doc/generator_iterator.htm">generator iterator adaptors</a> (moved to Boost.Iterator)</li>
+ <li><a href="../iterator/doc/html/iterator/algorithms/next_prior.html">next/prior</a> (moved to Boost.Iterator)</li>
+ <li><a href="../core/doc/html/core/noncopyable.html">noncopyable</a> (moved to Boost.Core)</li>
+ <li><a href="../io/doc/html/io.html">ostream_string</a> (moved to Boost.IO)</li>
+ </ul>
+ <hr>
+ <p>&copy; Copyright Beman Dawes, 2001</p>
+ <p>Distributed under the Boost Software License, Version 1.0. (See
+ accompanying file <a href="../../LICENSE_1_0.txt">
+ LICENSE_1_0.txt</a> or copy at
+ <a href="http://www.boost.org/LICENSE_1_0.txt">
+ www.boost.org/LICENSE_1_0.txt</a>)</p>
+ <p>Revised
+ <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->07 November, 2006<!--webbot bot="Timestamp" endspan i-checksum="39368" --></p>
+ </body>
+</html>
diff --git a/src/boost/libs/utility/iterator_adaptors.htm b/src/boost/libs/utility/iterator_adaptors.htm
new file mode 100644
index 000000000..7232ac297
--- /dev/null
+++ b/src/boost/libs/utility/iterator_adaptors.htm
@@ -0,0 +1,11 @@
+<!-- Copyright David Abrahams 2004. Distributed under the Boost -->
+<!-- Software License, Version 1.0. (See accompanying -->
+<!-- file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -->
+<html>
+<head>
+<meta http-equiv="refresh" content="0; URL=../iterator/doc/index.html">
+</head>
+<body>
+This documentation moved to <a href="../iterator/doc/index.html">../iterator/doc/index.html</a>.
+</body>
+</html>
diff --git a/src/boost/libs/utility/meta/libraries.json b/src/boost/libs/utility/meta/libraries.json
new file mode 100644
index 000000000..ca7c4b6e9
--- /dev/null
+++ b/src/boost/libs/utility/meta/libraries.json
@@ -0,0 +1,126 @@
+[
+ {
+ "key": "utility",
+ "name": "Utility",
+ "authors": [
+ "Dave Abrahams and others"
+ ],
+ "description": "Class noncopyable plus checked_delete(), checked_array_delete(), next(), prior() function templates, plus base-from-member idiom.",
+ "documentation": "utility.htm",
+ "category": [
+ "Algorithms",
+ "Function-objects",
+ "Memory",
+ "Miscellaneous",
+ "Patterns"
+ ]
+ },
+ {
+ "key": "utility/call_traits",
+ "name": "Call Traits",
+ "authors": [
+ "John Maddock, Howard Hinnant, et al"
+ ],
+ "description": "Defines types for passing parameters.",
+ "documentation": "call_traits.htm",
+ "category": [
+ "Generic"
+ ]
+ },
+ {
+ "key": "utility/compressed_pair",
+ "name": "Compressed Pair",
+ "authors": [
+ "John Maddock, Howard Hinnant, et al"
+ ],
+ "description": "Empty member optimization.",
+ "documentation": "compressed_pair.htm",
+ "category": [
+ "Data",
+ "Patterns"
+ ]
+ },
+ {
+ "key": "utility/identity_type",
+ "name": "Identity Type",
+ "authors": [
+ "Lorenzo Caminiti"
+ ],
+ "description": "Wrap types within round parenthesis so they can always be passed as macro parameters.",
+ "documentation": "identity_type/",
+ "category": [
+ "Preprocessor"
+ ],
+ "maintainers": [
+ "Lorenzo Caminiti <lorcaminiti -at- gmail.com>"
+ ]
+ },
+ {
+ "key": "utility/in_place_factories",
+ "name": "In Place Factory, Typed In Place Factory",
+ "authors": [
+ "Fernando Cacciola"
+ ],
+ "description": "Generic in-place construction of contained objects with a variadic argument-list.",
+ "documentation": "in_place_factories.html",
+ "category": [
+ "Generic"
+ ]
+ },
+ {
+ "key": "utility/operators",
+ "name": "Operators",
+ "authors": [
+ "Dave Abrahams",
+ "Jeremy Siek"
+ ],
+ "description": "Templates ease arithmetic classes and iterators.",
+ "documentation": "operators.htm",
+ "category": [
+ "Generic",
+ "Iterators",
+ "Math"
+ ],
+ "maintainers": [
+ "Daniel Frey <d.frey -at- gmx.de>"
+ ]
+ },
+ {
+ "key": "utility/result_of",
+ "name": "Result Of",
+ "description": "Determines the type of a function call expression.",
+ "documentation": "utility.htm#result_of",
+ "category": [
+ "Function-objects"
+ ],
+ "authors": "",
+ "maintainers": [
+ "Daniel Walker <daniel.j.walker -at- gmail.com>"
+ ]
+ },
+ {
+ "key": "utility/string_ref",
+ "name": "string_ref",
+ "description": "String view templates.",
+ "documentation": "doc/html/string_ref.html",
+ "category": [
+ "Containers"
+ ],
+ "authors": "Marshall Clow",
+ "maintainers": [
+ "Marshall Clow <marshall -at- idio.com>"
+ ]
+ },
+ {
+ "key": "utility/value_initialized",
+ "name": "Value Initialized",
+ "authors": [
+ "Fernando Cacciola"
+ ],
+ "description": "Wrapper for uniform-syntax value initialization, based on the original idea of David Abrahams.",
+ "documentation": "value_init.htm",
+ "category": [
+ "Miscellaneous"
+ ]
+ }
+]
diff --git a/src/boost/libs/utility/operators.htm b/src/boost/libs/utility/operators.htm
new file mode 100644
index 000000000..d2c6682cb
--- /dev/null
+++ b/src/boost/libs/utility/operators.htm
@@ -0,0 +1,2144 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
+
+<html>
+ <head>
+ <meta name="generator" content=
+ "HTML Tidy for Windows (vers 1st August 2002), see www.w3.org">
+ <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+
+ <title>Header &lt;boost/operators.hpp&gt; Documentation</title>
+ </head>
+
+ <body text="black" bgcolor="white" link="blue" vlink="purple" alink="red">
+ <h1><img src="../../boost.png" alt="boost.png (6897 bytes)" align=
+ "middle" width="277" height="86">Header <cite>&lt;<a href=
+ "../../boost/operators.hpp">boost/operators.hpp</a>&gt;</cite></h1>
+
+ <p>The header <cite>&lt;<a href=
+ "../../boost/operators.hpp">boost/operators.hpp</a>&gt;</cite> supplies
+ several sets of class templates (in namespace <code>boost</code>). These
+ templates define operators at namespace scope in terms of a minimal
+ number of fundamental operators provided by the class.</p>
+
+ <h2><a name="contents">Contents</a></h2>
+
+ <ul>
+ <li><a href="#contents">Contents</a></li>
+
+ <li>
+ <a href="#rationale">Rationale</a>
+
+ <ul>
+ <li><a href="#semantics">Summary of Template Semantics</a></li>
+
+ <li><a href="#concepts_note">Use of <i>concepts</i></a></li>
+ </ul>
+ </li>
+
+ <li>
+ <a href="#usage">Usage</a>
+
+ <ul>
+ <li>
+ <a href="#two_arg">Two-Argument Template Forms</a>
+
+ <ul>
+ <li><a href="#two_arg_gen">General Considerations</a></li>
+
+ <li><a href="#mixed_arithmetics">Mixed arithmetics</a></li>
+ </ul>
+ </li>
+
+ <li><a href="#chaining">Base Class Chaining and Object
+ Size</a></li>
+
+ <li><a href="#explicit_instantiation">Separate, Explicit
+ Instantiation</a></li>
+
+ <li><a href="#portability">Requirement Portability</a></li>
+ </ul>
+ </li>
+
+ <li><a href="#example">Example</a></li>
+
+ <li>
+ <a href="#arithmetic">Arithmetic operators</a>
+
+ <ul>
+ <li>
+ <a href="#smpl_oprs">Simple Arithmetic Operators</a>
+
+ <ul>
+ <li><a href="#ordering">Ordering Note</a></li>
+
+ <li><a href="#symmetry">Symmetry Note</a></li>
+ </ul>
+ </li>
+
+ <li><a href="#grpd_oprs">Grouped Arithmetic Operators</a></li>
+
+ <li><a href="#ex_oprs">Example Templates</a></li>
+
+ <li><a href="#a_demo">Arithmetic Operators Demonstration and Test
+ Program</a></li>
+ </ul>
+ </li>
+
+ <li>
+ <a href="#deref">Dereference Operators and Iterator Helpers</a>
+
+ <ul>
+ <li><a href="#dereference">Dereference operators</a></li>
+
+ <li><a href="#grpd_iter_oprs">Grouped Iterator Operators</a></li>
+
+ <li>
+ <a href="#iterator">Iterator Helpers</a>
+
+ <ul>
+ <li><a href="#iterator_helpers_notes">Iterator Helper
+ Notes</a></li>
+ </ul>
+ </li>
+
+ <li><a href="#i_demo">Iterator Demonstration and Test
+ Program</a></li>
+ </ul>
+ </li>
+
+ <li><a href="#contributors">Contributors</a></li>
+
+ <li><a href="#old_lib_note">Note for Users of Older Versions</a></li>
+ </ul>
+
+ <h2><a name="rationale">Rationale</a></h2>
+
+ <p>Overloaded operators for class types typically occur in groups. If you
+ can write <code>x&nbsp;+&nbsp;y</code>, you probably also want to be able
+ to write <code>x += y</code>. If you can write <code>x &lt; y,</code> you
+ also want <code>x &gt; y, x &gt;= y,</code> and <code>x &lt;= y</code>.
+ Moreover, unless your class has really surprising behavior, some of these
+ related operators can be defined in terms of others (e.g. <code>x &gt;= y
+ is equivalent to !(x &lt; y)</code>). Replicating this boilerplate for
+ multiple classes is both tedious and error-prone. The <cite><a href=
+ "../../boost/operators.hpp">boost/operators.hpp</a></cite> templates help
+ by generating operators for you at namespace scope based on other
+ operators you've defined in your class.</p>
+
+ <p>If, for example, you declare a class like this:</p>
+
+ <blockquote>
+<pre>
+class MyInt
+ : boost::operators&lt;MyInt&gt;
+{
+ bool operator&lt;(const MyInt&amp; x) const;
+ bool operator==(const MyInt&amp; x) const;
+ MyInt&amp; operator+=(const MyInt&amp; x);
+ MyInt&amp; operator-=(const MyInt&amp; x);
+ MyInt&amp; operator*=(const MyInt&amp; x);
+ MyInt&amp; operator/=(const MyInt&amp; x);
+ MyInt&amp; operator%=(const MyInt&amp; x);
+ MyInt&amp; operator|=(const MyInt&amp; x);
+ MyInt&amp; operator&amp;=(const MyInt&amp; x);
+ MyInt&amp; operator^=(const MyInt&amp; x);
+ MyInt&amp; operator++();
+ MyInt&amp; operator--();
+};
+</pre>
+ </blockquote>
+
+ <p>then the <code><a href="#operators1">operators&lt;&gt;</a></code>
+ template adds more than a dozen additional operators, such as
+ <code>operator&gt;</code>, <code>&lt;=</code>, <code>&gt;=</code>, and
+ (binary) <code>+</code>. <a href="#two_arg">Two-argument forms</a> of the
+ templates are also provided to allow interaction with other types.</p>
+
+ <h3>Summary of Template <a name="semantics">Semantics</a></h3>
+
+ <ol>
+ <li>Each operator template completes the concept(s) it describes by
+ defining overloaded operators for its target class.</li>
+
+ <li>The name of an operator class template indicates the <a href=
+ "#concepts_note">concept</a> that its target class will model.</li>
+
+ <li>Usually, the target class uses an instantation of the operator
+ class template as a base class. Some operator templates support an <a
+ href="#explicit_instantiation">alternate method</a>.</li>
+
+ <li>The concept can be compound, <i>i.e.</i> it may represent a common
+ combination of other, simpler concepts.</li>
+
+ <li>Most operator templates require their target class to support
+ operations related to the operators supplied by the template. In
+ accordance with widely accepted <a href=
+ "http://www.gotw.ca/gotw/004.htm">coding style recommendations</a>, the
+ target class is often required to supply the assignment counterpart
+ operator of the concept's "main operator." For example, the
+ <code>addable</code> template requires <code>operator+=(T
+ const&amp;)</code> and in turn supplies <code>operator+(T const&amp;, T
+ const&amp;)</code>.</li>
+ </ol>
+
+ <h3>Use of <i><a name="concepts_note">concepts</a></i></h3>
+
+ <p>The discussed concepts are not necessarily the standard library's
+ concepts (CopyConstructible, <i>etc.</i>), although some of them could
+ be; they are what we call <i>concepts with a small 'c'</i>. In
+ particular, they are different from the former ones in that they <em>do
+ not</em> describe precise semantics of the operators they require to be
+ defined, except the requirements that (a) the semantics of the operators
+ grouped in one concept should be consistent (<i>e.g.</i> effects of
+ evaluating of <code>a += b</code> and
+ <code>a&nbsp;=&nbsp;a&nbsp;+&nbsp;b</code> expressions should be the
+ same), and (b) that the return types of the operators should follow
+ semantics of return types of corresponding operators for built-in types
+ (<i>e.g.</i> <code>operator&lt;</code> should return a type convertible
+ to <code>bool</code>, and <code>T::operator-=</code> should return type
+ convertible to <code>T</code>). Such "loose" requirements make operators
+ library applicable to broader set of target classes from different
+ domains, <i>i.e.</i> eventually more useful.</p>
+
+ <h2><a name="usage">Usage</a></h2>
+
+ <h3><a name="two_arg">Two-Argument</a> Template Forms</h3>
+
+ <h4><a name="two_arg_gen">General Considerations</a></h4>
+
+ <p>The arguments to a binary operator commonly have identical types, but
+ it is not unusual to want to define operators which combine different
+ types. For <a href="#example">example</a>, one might want to multiply a
+ mathematical vector by a scalar. The two-argument template forms of the
+ arithmetic operator templates are supplied for this purpose. When
+ applying the two-argument form of a template, the desired return type of
+ the operators typically determines which of the two types in question
+ should be derived from the operator template. For example, if the result
+ of <code>T&nbsp;+&nbsp;U</code> is of type <code>T</code>, then
+ <code>T</code> (not <code>U</code>) should be derived from <code><a href=
+ "#addable2">addable&lt;T, U&gt;</a></code>. The comparison templates
+ (<code><a href="#less_than_comparable2">less_than_comparable&lt;T,
+ U&gt;</a></code>, <code><a href=
+ "#equality_comparable2">equality_comparable&lt;T, U&gt;</a></code>,
+ <code><a href="#equivalent2">equivalent&lt;T, U&gt;</a></code>, and
+ <code><a href="#partially_ordered2">partially_ordered&lt;T,
+ U&gt;</a></code>) are exceptions to this guideline, since the return type
+ of the operators they define is <code>bool</code>.</p>
+
+ <p>On compilers which do not support partial specialization, the
+ two-argument forms must be specified by using the names shown below with
+ the trailing <code>'2'</code>. The single-argument forms with the
+ trailing <code>'1'</code> are provided for symmetry and to enable certain
+ applications of the <a href="#chaining">base class chaining</a>
+ technique.</p>
+
+ <h4><a name="mixed_arithmetics">Mixed Arithmetics</a></h4>
+
+ <p>Another application of the two-argument template forms is for mixed
+ arithmetics between a type <code>T</code> and a type <code>U</code> that
+ is convertible to <code>T</code>. In this case there are two ways where
+ the two-argument template forms are helpful: one is to provide the
+ respective signatures for operator overloading, the second is
+ performance.</p>
+
+ <p>With respect to the operator overloading assume <i>e.g.</i> that
+ <code>U</code> is <code>int</code>, that <code>T</code> is an
+ user-defined unlimited integer type, and that <code>double
+ operator-(double, const T&amp;)</code> exists. If one wants to compute
+ <code>int - T</code> and does not provide <code>T operator-(int, const
+ T&amp;)</code>, the compiler will consider <code>double operator-(double,
+ const T&amp;)</code> to be a better match than <code>T operator-(const
+ T&amp;, const T&amp;)</code>, which will probably be different from the
+ user's intention. To define a complete set of operator signatures,
+ additional 'left' forms of the two-argument template forms are provided
+ (<code><a href="#subtractable2_left">subtractable2_left&lt;T,
+ U&gt;</a></code>, <code><a href="#dividable2_left">dividable2_left&lt;T,
+ U&gt;</a></code>, <code><a href="#modable2_left">modable2_left&lt;T,
+ U&gt;</a></code>) that define the signatures for non-commutative
+ operators where <code>U</code> appears on the left hand side
+ (<code>operator-(const U&amp;, const T&amp;)</code>,
+ <code>operator/(const U&amp;, const T&amp;)</code>, <code>operator%(const
+ U&amp;, const T&amp;)</code>).</p>
+
+ <p>With respect to the performance observe that when one uses the single
+ type binary operator for mixed type arithmetics, the type <code>U</code>
+ argument has to be converted to type <code>T</code>. In practice,
+ however, there are often more efficient implementations of, say
+ <code>T::operator-=(const U&amp;)</code> that avoid unnecessary
+ conversions from <code>U</code> to <code>T</code>. The two-argument
+ template forms of the arithmetic operator create additional operator
+ interfaces that use these more efficient implementations. There is,
+ however, no performance gain in the 'left' forms: they still need a
+ conversion from <code>U</code> to <code>T</code> and have an
+ implementation equivalent to the code that would be automatically created
+ by the compiler if it considered the single type binary operator to be
+ the best match.</p>
+
+ <h3>Base Class <a name="chaining">Chaining</a> and Object Size</h3>
+
+ <p>Every operator class template, except the <a href=
+ "#ex_oprs">arithmetic examples</a> and the <a href="#iterator">iterator
+ helpers</a>, has an additional, but optional, template type parameter
+ <code>B</code>. This parameter will be a publicly-derived base class of
+ the instantiated template. This means it must be a class type. It can be
+ used to avoid the bloating of object sizes that is commonly associated
+ with multiple-inheritance from several empty base classes (see the <a
+ href="#old_lib_note">note for users of older versions</a> for more
+ details). To provide support for a group of operators, use the
+ <code>B</code> parameter to chain operator templates into a single-base
+ class hierarchy, demostrated in the <a href="#example">usage example</a>.
+ The technique is also used by the composite operator templates to group
+ operator definitions. If a chain becomes too long for the compiler to
+ support, try replacing some of the operator templates with a single
+ grouped operator template that chains the old templates together; the
+ length limit only applies to the number of templates directly in the
+ chain, not those hidden in group templates.</p>
+
+ <p><strong>Caveat:</strong> to chain to a base class which is
+ <em>not</em> a Boost operator template when using the <a href=
+ "#two_arg">single-argument form</a> of a Boost operator template, you
+ must specify the operator template with the trailing <code>'1'</code> in
+ its name. Otherwise the library will assume you mean to define a binary
+ operation combining the class you intend to use as a base class and the
+ class you're deriving.</p>
+
+ <h3>Separate, <a name="explicit_instantiation">Explicit
+ Instantiation</a></h3>
+
+ <p>On some compilers (<i>e.g.</i> Borland, GCC) even single-inheritance
+ seems to cause an increase in object size in some cases. If you are not
+ defining a class template, you may get better object-size performance by
+ avoiding derivation altogether, and instead explicitly instantiating the
+ operator template as follows:</p>
+
+ <blockquote>
+<pre>
+ class myclass // lose the inheritance...
+ {
+ //...
+ };
+
+ // explicitly instantiate the operators I need.
+ template struct less_than_comparable&lt;myclass&gt;;
+ template struct equality_comparable&lt;myclass&gt;;
+ template struct incrementable&lt;myclass&gt;;
+ template struct decrementable&lt;myclass&gt;;
+ template struct addable&lt;myclass,long&gt;;
+ template struct subtractable&lt;myclass,long&gt;;
+</pre>
+ </blockquote>
+
+ <p>Note that some operator templates cannot use this workaround and must
+ be a base class of their primary operand type. Those templates define
+ operators which must be member functions, and the workaround needs the
+ operators to be independent friend functions. The relevant templates
+ are:</p>
+
+ <ul>
+ <li><code><a href=
+ "#dereferenceable">dereferenceable&lt;&gt;</a></code></li>
+
+ <li><code><a href="#indexable">indexable&lt;&gt;</a></code></li>
+
+ <li>Any composite operator template that includes at least one of the
+ above</li>
+ </ul>
+
+ <p>As Daniel Kr&uuml;gler pointed out, this technique violates 14.6.5/2
+ and is thus non-portable. The reasoning is, that the operators injected
+ by the instantiation of e.g.
+ <code>less_than_comparable&lt;myclass&gt;</code> can not be found
+ by ADL according to the rules given by 3.4.2/2, since myclass is
+ not an associated class of
+ <code>less_than_comparable&lt;myclass&gt;</code>.
+ Thus only use this technique if all else fails.</p>
+
+ <h3>Requirement <a name="portability">Portability</a></h3>
+
+ <p>Many compilers (<i>e.g.</i> MSVC 6.3, GCC 2.95.2) will not enforce the
+ requirements in the operator template tables unless the operations which
+ depend on them are actually used. This is not standard-conforming
+ behavior. In particular, although it would be convenient to derive all
+ your classes which need binary operators from the <code><a href=
+ "#operators1">operators&lt;&gt;</a></code> and <code><a href=
+ "#operators2">operators2&lt;&gt;</a></code> templates, regardless of
+ whether they implement all the requirements of those templates, this
+ shortcut is not portable. Even if this currently works with your
+ compiler, it may not work later.</p>
+
+ <h2><a name="example">Example</a></h2>
+
+ <p>This example shows how some of the <a href="#arithmetic">arithmetic
+ operator templates</a> can be used with a geometric point class
+ (template).</p>
+<pre>
+template &lt;class T&gt;
+class point // note: private inheritance is OK here!
+ : boost::addable&lt; point&lt;T&gt; // point + point
+ , boost::subtractable&lt; point&lt;T&gt; // point - point
+ , boost::dividable2&lt; point&lt;T&gt;, T // point / T
+ , boost::multipliable2&lt; point&lt;T&gt;, T // point * T, T * point
+ &gt; &gt; &gt; &gt;
+{
+public:
+ point(T, T);
+ T x() const;
+ T y() const;
+
+ point operator+=(const point&amp;);
+ // point operator+(point, const point&amp;) automatically
+ // generated by addable.
+
+ point operator-=(const point&amp;);
+ // point operator-(point, const point&amp;) automatically
+ // generated by subtractable.
+
+ point operator*=(T);
+ // point operator*(point, const T&amp;) and
+ // point operator*(const T&amp;, point) auto-generated
+ // by multipliable.
+
+ point operator/=(T);
+ // point operator/(point, const T&amp;) auto-generated
+ // by dividable.
+private:
+ T x_;
+ T y_;
+};
+
+// now use the point&lt;&gt; class:
+
+template &lt;class T&gt;
+T length(const point&lt;T&gt; p)
+{
+ return sqrt(p.x()*p.x() + p.y()*p.y());
+}
+
+const point&lt;float&gt; right(0, 1);
+const point&lt;float&gt; up(1, 0);
+const point&lt;float&gt; pi_over_4 = up + right;
+const point&lt;float&gt; pi_over_4_normalized = pi_over_4 / length(pi_over_4);
+</pre>
+
+ <h2><a name="arithmetic">Arithmetic</a> Operators</h2>
+
+ <p>The arithmetic operator templates ease the task of creating a custom
+ numeric type. Given a core set of operators, the templates add related
+ operators to the numeric class. These operations are like the ones the
+ standard arithmetic types have, and may include comparisons, adding,
+ incrementing, logical and bitwise manipulations, <i>etc</i>. Further,
+ since most numeric types need more than one of these operators, some
+ templates are provided to combine several of the basic operator templates
+ in one declaration.</p>
+
+ <p>The requirements for the types used to instantiate the simple operator
+ templates are specified in terms of expressions which must be valid and
+ the expression's return type. The composite operator templates only list
+ what other templates they use. The supplied operations and requirements
+ of the composite operator templates can be inferred from the operations
+ and requirements of the listed components.</p>
+
+ <h3><a name="smpl_oprs">Simple Arithmetic Operators</a></h3>
+
+ <p>These templates are "simple" since they provide operators based on a
+ single operation the base type has to provide. They have an additional
+ optional template parameter <code>B</code>, which is not shown, for the
+ <a href="#chaining">base class chaining</a> technique.</p>
+
+ <p>The primary operand type <code>T</code> needs to be of class type,
+ built-in types are not supported.</p>
+
+ <table cellpadding="5" border="1" align="center">
+ <caption>
+ Simple Arithmetic Operator Template Classes
+ </caption>
+
+ <tr>
+ <td colspan="3">
+ <table align="center" border="1">
+ <caption>
+ <em>Key</em>
+ </caption>
+
+ <tr>
+ <td><code>T</code>: primary operand type</td>
+
+ <td><code>U</code>: alternate operand type</td>
+ </tr>
+
+ <tr>
+ <td><code>t</code>, <code>t1</code>: values of type
+ <code>T</code></td>
+
+ <td><code>u</code>: value of type <code>U</code></td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+
+ <tr>
+ <th>Template</th>
+
+ <th>Supplied Operations</th>
+
+ <th>Requirements</th>
+ </tr>
+
+ <tr>
+ <td><code><a name=
+ "less_than_comparable1">less_than_comparable&lt;T&gt;</a></code><br>
+ <code>less_than_comparable1&lt;T&gt;</code></td>
+
+ <td><code>bool operator&gt;(const T&amp;, const T&amp;)</code><br>
+ <code>bool operator&lt;=(const T&amp;, const T&amp;)</code><br>
+ <code>bool operator&gt;=(const T&amp;, const T&amp;)</code></td>
+
+ <td><code>t &lt; t1</code>.<br>
+ Return convertible to <code>bool</code>. See the <a href=
+ "#ordering">Ordering Note</a>.</td>
+ </tr>
+
+ <tr>
+ <td><code><a name="less_than_comparable2">less_than_comparable&lt;T,
+ U&gt;</a></code><br>
+ <code>less_than_comparable2&lt;T, U&gt;</code></td>
+
+ <td><code>bool operator&lt;=(const T&amp;, const U&amp;)</code><br>
+ <code>bool operator&gt;=(const T&amp;, const U&amp;)</code><br>
+ <code>bool operator&gt;(const U&amp;, const T&amp;)</code><br>
+ <code>bool operator&lt;(const U&amp;, const T&amp;)</code><br>
+ <code>bool operator&lt;=(const U&amp;, const T&amp;)</code><br>
+ <code>bool operator&gt;=(const U&amp;, const T&amp;)</code></td>
+
+ <td><code>t &lt; u</code>. <code>t &gt; u</code>.<br>
+ Returns convertible to <code>bool</code>. See the <a href=
+ "#ordering">Ordering Note</a>.</td>
+ </tr>
+
+ <tr>
+ <td><code><a name=
+ "equality_comparable1">equality_comparable&lt;T&gt;</a></code><br>
+ <code>equality_comparable1&lt;T&gt;</code></td>
+
+ <td><code>bool operator!=(const T&amp;, const T&amp;)</code></td>
+
+ <td><code>t == t1</code>.<br>
+ Return convertible to <code>bool</code>.</td>
+ </tr>
+
+ <tr>
+ <td><code><a name="equality_comparable2">equality_comparable&lt;T,
+ U&gt;</a></code><br>
+ <code>equality_comparable2&lt;T, U&gt;</code></td>
+
+ <td><code>bool operator==(const U&amp;, const T&amp;)</code><br>
+ <code>bool operator!=(const U&amp;, const T&amp;)</code><br>
+ <code>bool operator!=(const T&amp;, const U&amp;)</code></td>
+
+ <td><code>t == u</code>.<br>
+ Return convertible to <code>bool</code>.</td>
+ </tr>
+
+ <tr>
+ <td><code><a name="addable1">addable&lt;T&gt;</a></code><br>
+ <code>addable1&lt;T&gt;</code></td>
+
+ <td><code>T operator+(const T&amp;, const T&amp;)</code></td>
+
+ <td><code>T temp(t); temp += t1</code>.<br>
+ Return convertible to <code>T</code>. See the <a href=
+ "#symmetry">Symmetry Note</a>.</td>
+ </tr>
+
+ <tr>
+ <td><code><a name="addable2">addable&lt;T, U&gt;</a></code><br>
+ <code>addable2&lt;T, U&gt;</code></td>
+
+ <td><code>T operator+(const T&amp;, const U&amp;)</code><br>
+ <code>T operator+(const U&amp;, const T&amp; )</code></td>
+
+ <td><code>T temp(t); temp += u</code>.<br>
+ Return convertible to <code>T</code>. See the <a href=
+ "#symmetry">Symmetry Note</a>.</td>
+ </tr>
+
+ <tr>
+ <td><code><a name=
+ "subtractable1">subtractable&lt;T&gt;</a></code><br>
+ <code>subtractable1&lt;T&gt;</code></td>
+
+ <td><code>T operator-(const T&amp;, const T&amp;)</code></td>
+
+ <td><code>T temp(t); temp -= t1</code>.<br>
+ Return convertible to <code>T</code>. See the <a href=
+ "#symmetry">Symmetry Note</a>.</td>
+ </tr>
+
+ <tr>
+ <td><code><a name="subtractable2">subtractable&lt;T,
+ U&gt;</a></code><br>
+ <code>subtractable2&lt;T, U&gt;</code></td>
+
+ <td><code>T operator-(const T&amp;, const U&amp;)</code></td>
+
+ <td><code>T temp(t); temp -= u</code>.<br>
+ Return convertible to <code>T</code>. See the <a href=
+ "#symmetry">Symmetry Note</a>.</td>
+ </tr>
+
+ <tr>
+ <td><code><a name="subtractable2_left">subtractable2_left&lt;T,
+ U&gt;</a></code></td>
+
+ <td><code>T operator-(const U&amp;, const T&amp;)</code></td>
+
+ <td><code>T temp(u); temp -= t</code>.<br>
+ Return convertible to <code>T</code>.</td>
+ </tr>
+
+ <tr>
+ <td><code><a name=
+ "multipliable1">multipliable&lt;T&gt;</a></code><br>
+ <code>multipliable1&lt;T&gt;</code></td>
+
+ <td><code>T operator*(const T&amp;, const T&amp;)</code></td>
+
+ <td><code>T temp(t); temp *= t1</code>.<br>
+ Return convertible to <code>T</code>. See the <a href=
+ "#symmetry">Symmetry Note</a>.</td>
+ </tr>
+
+ <tr>
+ <td><code><a name="multipliable2">multipliable&lt;T,
+ U&gt;</a></code><br>
+ <code>multipliable2&lt;T, U&gt;</code></td>
+
+ <td><code>T operator*(const T&amp;, const U&amp;)</code><br>
+ <code>T operator*(const U&amp;, const T&amp;)</code></td>
+
+ <td><code>T temp(t); temp *= u</code>.<br>
+ Return convertible to <code>T</code>. See the <a href=
+ "#symmetry">Symmetry Note</a>.</td>
+ </tr>
+
+ <tr>
+ <td><code><a name="dividable1">dividable&lt;T&gt;</a></code><br>
+ <code>dividable1&lt;T&gt;</code></td>
+
+ <td><code>T operator/(const T&amp;, const T&amp;)</code></td>
+
+ <td><code>T temp(t); temp /= t1</code>.<br>
+ Return convertible to <code>T</code>. See the <a href=
+ "#symmetry">Symmetry Note</a>.</td>
+ </tr>
+
+ <tr>
+ <td><code><a name="dividable2">dividable&lt;T, U&gt;</a></code><br>
+ <code>dividable2&lt;T, U&gt;</code></td>
+
+ <td><code>T operator/(const T&amp;, const U&amp;)</code></td>
+
+ <td><code>T temp(t); temp /= u</code>.<br>
+ Return convertible to <code>T</code>. See the <a href=
+ "#symmetry">Symmetry Note</a>.</td>
+ </tr>
+
+ <tr>
+ <td><code><a name="dividable2_left">dividable2_left&lt;T,
+ U&gt;</a></code></td>
+
+ <td><code>T operator/(const U&amp;, const T&amp;)</code></td>
+
+ <td><code>T temp(u); temp /= t</code>.<br>
+ Return convertible to <code>T</code>.</td>
+ </tr>
+
+ <tr>
+ <td><code><a name="modable1">modable&lt;T&gt;</a></code><br>
+ <code>modable1&lt;T&gt;</code></td>
+
+ <td><code>T operator%(const T&amp;, const T&amp;)</code></td>
+
+ <td><code>T temp(t); temp %= t1</code>.<br>
+ Return convertible to <code>T</code>. See the <a href=
+ "#symmetry">Symmetry Note</a>.</td>
+ </tr>
+
+ <tr>
+ <td><code><a name="modable2">modable&lt;T, U&gt;</a></code><br>
+ <code>modable2&lt;T, U&gt;</code></td>
+
+ <td><code>T operator%(const T&amp;, const U&amp;)</code></td>
+
+ <td><code>T temp(t); temp %= u</code>.<br>
+ Return convertible to <code>T</code>. See the <a href=
+ "#symmetry">Symmetry Note</a>.</td>
+ </tr>
+
+ <tr>
+ <td><code><a name="modable2_left">modable2_left&lt;T,
+ U&gt;</a></code></td>
+
+ <td><code>T operator%(const U&amp;, const T&amp;)</code></td>
+
+ <td><code>T temp(u); temp %= t</code>.<br>
+ Return convertible to <code>T</code>.</td>
+ </tr>
+
+ <tr>
+ <td><code><a name="orable1">orable&lt;T&gt;</a></code><br>
+ <code>orable1&lt;T&gt;</code></td>
+
+ <td><code>T operator|(const T&amp;, const T&amp;)</code></td>
+
+ <td><code>T temp(t); temp |= t1</code>.<br>
+ Return convertible to <code>T</code>. See the <a href=
+ "#symmetry">Symmetry Note</a>.</td>
+ </tr>
+
+ <tr>
+ <td><code><a name="orable2">orable&lt;T, U&gt;</a></code><br>
+ <code>orable2&lt;T, U&gt;</code></td>
+
+ <td><code>T operator|(const T&amp;, const U&amp;)</code><br>
+ <code>T operator|(const U&amp;, const T&amp;)</code></td>
+
+ <td><code>T temp(t); temp |= u</code>.<br>
+ Return convertible to <code>T</code>. See the <a href=
+ "#symmetry">Symmetry Note</a>.</td>
+ </tr>
+
+ <tr>
+ <td><code><a name="andable1">andable&lt;T&gt;</a></code><br>
+ <code>andable1&lt;T&gt;</code></td>
+
+ <td><code>T operator&amp;(const T&amp;, const T&amp;)</code></td>
+
+ <td><code>T temp(t); temp &amp;= t1</code>.<br>
+ Return convertible to <code>T</code>. See the <a href=
+ "#symmetry">Symmetry Note</a>.</td>
+ </tr>
+
+ <tr>
+ <td><code><a name="andable2">andable&lt;T, U&gt;</a></code><br>
+ <code>andable2&lt;T, U&gt;</code></td>
+
+ <td><code>T operator&amp;(const T&amp;, const U&amp;)</code><br>
+ <code>T operator&amp;(const U&amp;, const T&amp;)</code></td>
+
+ <td><code>T temp(t); temp &amp;= u</code>.<br>
+ Return convertible to <code>T</code>. See the <a href=
+ "#symmetry">Symmetry Note</a>.</td>
+ </tr>
+
+ <tr>
+ <td><code><a name="xorable1">xorable&lt;T&gt;</a></code><br>
+ <code>xorable1&lt;T&gt;</code></td>
+
+ <td><code>T operator^(const T&amp;, const T&amp;)</code></td>
+
+ <td><code>T temp(t); temp ^= t1</code>.<br>
+ Return convertible to <code>T</code>. See the <a href=
+ "#symmetry">Symmetry Note</a>.</td>
+ </tr>
+
+ <tr>
+ <td><code><a name="xorable2">xorable&lt;T, U&gt;</a></code><br>
+ <code>xorable2&lt;T, U&gt;</code></td>
+
+ <td><code>T operator^(const T&amp;, const U&amp;)</code><br>
+ <code>T operator^(const U&amp;, const T&amp;)</code></td>
+
+ <td><code>T temp(t); temp ^= u</code>.<br>
+ Return convertible to <code>T</code>. See the <a href=
+ "#symmetry">Symmetry Note</a>.</td>
+ </tr>
+
+ <tr>
+ <td><code><a name=
+ "incrementable">incrementable&lt;T&gt;</a></code></td>
+
+ <td><code>T operator++(T&amp;, int)</code></td>
+
+ <td><code>T temp(t); ++t</code><br>
+ Return convertible to <code>T</code>.</td>
+ </tr>
+
+ <tr>
+ <td><code><a name=
+ "decrementable">decrementable&lt;T&gt;</a></code></td>
+
+ <td><code>T operator--(T&amp;, int)</code></td>
+
+ <td><code>T temp(t); --t;</code><br>
+ Return convertible to <code>T</code>.</td>
+ </tr>
+
+ <tr>
+ <td><code><a name=
+ "left_shiftable1">left_shiftable&lt;T&gt;</a></code><br>
+ <code>left_shiftable1&lt;T&gt;</code></td>
+
+ <td><code>T operator&lt;&lt;(const T&amp;, const T&amp;)</code></td>
+
+ <td><code>T temp(t); temp &lt;&lt;= t1</code>.<br>
+ Return convertible to <code>T</code>. See the <a href=
+ "#symmetry">Symmetry Note</a>.</td>
+ </tr>
+
+ <tr>
+ <td><code><a name="left_shiftable2">left_shiftable&lt;T,
+ U&gt;</a></code><br>
+ <code>left_shiftable2&lt;T, U&gt;</code></td>
+
+ <td><code>T operator&lt;&lt;(const T&amp;, const U&amp;)</code></td>
+
+ <td><code>T temp(t); temp &lt;&lt;= u</code>.<br>
+ Return convertible to <code>T</code>. See the <a href=
+ "#symmetry">Symmetry Note</a>.</td>
+ </tr>
+
+ <tr>
+ <td><code><a name=
+ "right_shiftable1">right_shiftable&lt;T&gt;</a></code><br>
+ <code>right_shiftable1&lt;T&gt;</code></td>
+
+ <td><code>T operator&gt;&gt;(const T&amp;, const T&amp;)</code></td>
+
+ <td><code>T temp(t); temp &gt;&gt;= t1</code>.<br>
+ Return convertible to <code>T</code>. See the <a href=
+ "#symmetry">Symmetry Note</a>.</td>
+ </tr>
+
+ <tr>
+ <td><code><a name="right_shiftable2">right_shiftable&lt;T,
+ U&gt;</a></code><br>
+ <code>right_shiftable2&lt;T, U&gt;</code></td>
+
+ <td><code>T operator&gt;&gt;(const T&amp;, const U&amp;)</code></td>
+
+ <td><code>T temp(t); temp &gt;&gt;= u</code>.<br>
+ Return convertible to <code>T</code>. See the <a href=
+ "#symmetry">Symmetry Note</a>.</td>
+ </tr>
+
+ <tr>
+ <td><code><a name="equivalent1">equivalent&lt;T&gt;</a></code><br>
+ <code>equivalent1&lt;T&gt;</code></td>
+
+ <td><code>bool operator==(const T&amp;, const T&amp;)</code></td>
+
+ <td><code>t &lt; t1</code>.<br>
+ Return convertible to <code>bool</code>. See the <a href=
+ "#ordering">Ordering Note</a>.</td>
+ </tr>
+
+ <tr>
+ <td><code><a name="equivalent2">equivalent&lt;T, U&gt;</a></code><br>
+ <code>equivalent2&lt;T, U&gt;</code></td>
+
+ <td><code>bool operator==(const T&amp;, const U&amp;)</code></td>
+
+ <td><code>t &lt; u</code>. <code>t &gt; u</code>.<br>
+ Returns convertible to <code>bool</code>. See the <a href=
+ "#ordering">Ordering Note</a>.</td>
+ </tr>
+
+ <tr>
+ <td><code><a name=
+ "partially_ordered1">partially_ordered&lt;T&gt;</a></code><br>
+ <code>partially_ordered1&lt;T&gt;</code></td>
+
+ <td><code>bool operator&gt;(const T&amp;, const T&amp;)</code><br>
+ <code>bool operator&lt;=(const T&amp;, const T&amp;)</code><br>
+ <code>bool operator&gt;=(const T&amp;, const T&amp;)</code></td>
+
+ <td><code>t &lt; t1</code>. <code>t == t1</code>.<br>
+ Returns convertible to <code>bool</code>. See the <a href=
+ "#ordering">Ordering Note</a>.</td>
+ </tr>
+
+ <tr>
+ <td><code><a name="partially_ordered2">partially_ordered&lt;T,
+ U&gt;</a></code><br>
+ <code>partially_ordered2&lt;T, U&gt;</code></td>
+
+ <td><code>bool operator&lt;=(const T&amp;, const U&amp;)</code><br>
+ <code>bool operator&gt;=(const T&amp;, const U&amp;)</code><br>
+ <code>bool operator&gt;(const U&amp;, const T&amp;)</code><br>
+ <code>bool operator&lt;(const U&amp;, const T&amp;)</code><br>
+ <code>bool operator&lt;=(const U&amp;, const T&amp;)</code><br>
+ <code>bool operator&gt;=(const U&amp;, const T&amp;)</code></td>
+
+ <td><code>t &lt; u</code>. <code>t &gt; u</code>. <code>t ==
+ u</code>.<br>
+ Returns convertible to <code>bool</code>. See the <a href=
+ "#ordering">Ordering Note</a>.</td>
+ </tr>
+ </table>
+
+ <h4><a name="ordering">Ordering</a> Note</h4>
+
+ <p>The <code><a href=
+ "#less_than_comparable1">less_than_comparable&lt;T&gt;</a></code> and
+ <code><a href="#partially_ordered1">partially_ordered&lt;T&gt;</a></code>
+ templates provide the same set of operations. However, the workings of
+ <code><a href=
+ "#less_than_comparable1">less_than_comparable&lt;T&gt;</a></code> assume
+ that all values of type <code>T</code> can be placed in a total order. If
+ that is not true (<i>e.g.</i> Not-a-Number values in IEEE floating point
+ arithmetic), then <code><a href=
+ "#partially_ordered1">partially_ordered&lt;T&gt;</a></code> should be
+ used. The <code><a href=
+ "#partially_ordered1">partially_ordered&lt;T&gt;</a></code> template can
+ be used for a totally-ordered type, but it is not as efficient as
+ <code><a href=
+ "#less_than_comparable1">less_than_comparable&lt;T&gt;</a></code>. This
+ rule also applies for <code><a href=
+ "#less_than_comparable2">less_than_comparable&lt;T, U&gt;</a></code> and
+ <code><a href="#partially_ordered2">partially_ordered&lt;T,
+ U&gt;</a></code> with respect to the ordering of all <code>T</code> and
+ <code>U</code> values, and for both versions of <code><a href=
+ "#equivalent1">equivalent&lt;&gt;</a></code>. The solution for <code><a
+ href="#equivalent1">equivalent&lt;&gt;</a></code> is to write a custom
+ <code>operator==</code> for the target class.</p>
+
+ <h4><a name="symmetry">Symmetry</a> Note</h4>
+
+ <p>Before talking about symmetry, we need to talk about optimizations to
+ understand the reasons for the different implementation styles of
+ operators. Let's have a look at <code>operator+</code> for a class
+ <code>T</code> as an example:</p>
+<pre>
+T operator+( const T&amp; lhs, const T&amp; rhs )
+{
+ return T( lhs ) += rhs;
+}
+</pre>
+ This would be a normal implementation of <code>operator+</code>, but it
+ is not an efficient one. An unnamed local copy of <code>lhs</code> is
+ created, <code>operator+=</code> is called on it and it is copied to the
+ function return value (which is another unnamed object of type
+ <code>T</code>). The standard doesn't generally allow the intermediate
+ object to be optimized away:
+
+ <blockquote>
+ 3.7.2/2: Automatic storage duration<br>
+ <br>
+ If a named automatic object has initialization or a destructor with
+ side effects, it shall not be destroyed before the end of its block,
+ nor shall it be eliminated as an optimization even if it appears to be
+ unused, except that a class object or its copy may be eliminated as
+ specified in 12.8.
+ </blockquote>
+ The reference to 12.8 is important for us:
+
+ <blockquote>
+ 12.8/15: Copying class objects<br>
+ ...<br>
+ For a function with a class return type, if the expression in the
+ return statement is the name of a local object, and the cv-unqualified
+ type of the local object is the same as the function return type, an
+ implementation is permitted to omit creating the temporary object to
+ hold the function return value, even if the class copy constructor or
+ destructor has side effects.
+ </blockquote>
+ This optimization is known as the named return value optimization (NRVO),
+ which leads us to the following implementation for
+ <code>operator+</code>:
+<pre>
+T operator+( const T&amp; lhs, const T&amp; rhs )
+{
+ T nrv( lhs );
+ nrv += rhs;
+ return nrv;
+}
+</pre>
+ Given this implementation, the compiler is allowed to remove the
+ intermediate object. Sadly, not all compiler implement the NRVO, some
+ even implement it in an incorrect way which makes it useless here.
+ Without the NRVO, the NRVO-friendly code is no worse than the original
+ code showed above, but there is another possible implementation, which
+ has some very special properties:
+<pre>
+T operator+( T lhs, const T&amp; rhs )
+{
+ return lhs += rhs;
+}
+</pre>
+ The difference to the first implementation is that <code>lhs</code> is
+ not taken as a constant reference used to create a copy; instead,
+ <code>lhs</code> is a by-value parameter, thus it is already the copy
+ needed. This allows another optimization (12.2/2) for some cases.
+ Consider <code>a&nbsp;+&nbsp;b&nbsp;+&nbsp;c</code> where the result of
+ <code>a&nbsp;+&nbsp;b</code> is not copied when used as <code>lhs</code>
+ when adding <code>c</code>. This is more efficient than the original
+ code, but not as efficient as a compiler using the NRVO. For most people,
+ it is still preferable for compilers that don't implement the NRVO, but
+ the <code>operator+</code> now has a different function signature. Also,
+ the number of objects created differs for
+ <code>(a&nbsp;+&nbsp;b&nbsp;)&nbsp;+&nbsp;c</code> and
+ <code>a&nbsp;+&nbsp;(&nbsp;b&nbsp;+&nbsp;c&nbsp;)</code>. Most probably,
+ this won't be a problem for you, but if your code relies on the function
+ signature or a strict symmetric behaviour, you should set
+ <code>BOOST_FORCE_SYMMETRIC_OPERATORS</code> in your user-config. This
+ will force the NRVO-friendly implementation to be used even for compilers
+ that don't implement the NRVO. <br>
+ <br>
+
+ <h3><a name="grpd_oprs">Grouped Arithmetic Operators</a></h3>
+
+ <p>The following templates provide common groups of related operations.
+ For example, since a type which is addable is usually also subractable,
+ the <code><a href="#additive1">additive</a></code> template provides the
+ combined operators of both. The grouped operator templates have an
+ additional optional template parameter <code>B</code>, which is not
+ shown, for the <a href="#chaining">base class chaining</a> technique.</p>
+
+ <table cellpadding="5" border="1" align="center">
+ <caption>
+ Grouped Arithmetic Operator Template Classes
+ </caption>
+
+ <tr>
+ <td colspan="2">
+ <table align="center" border="1">
+ <caption>
+ <em>Key</em>
+ </caption>
+
+ <tr>
+ <td><code>T</code>: primary operand type</td>
+
+ <td><code>U</code>: alternate operand type</td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+
+ <tr>
+ <th>Template</th>
+
+ <th>Component Operator Templates</th>
+ </tr>
+
+ <tr>
+ <td><code><a name=
+ "totally_ordered1">totally_ordered&lt;T&gt;</a></code><br>
+ <code>totally_ordered1&lt;T&gt;</code></td>
+
+ <td>
+ <ul>
+ <li><code><a href=
+ "#less_than_comparable1">less_than_comparable&lt;T&gt;</a></code></li>
+
+ <li><code><a href=
+ "#equality_comparable1">equality_comparable&lt;T&gt;</a></code></li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code><a name="totally_ordered2">totally_ordered&lt;T,
+ U&gt;</a></code><br>
+ <code>totally_ordered2&lt;T, U&gt;</code></td>
+
+ <td>
+ <ul>
+ <li><code><a href=
+ "#less_than_comparable2">less_than_comparable&lt;T,
+ U&gt;</a></code></li>
+
+ <li><code><a href=
+ "#equality_comparable2">equality_comparable&lt;T,
+ U&gt;</a></code></li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code><a name="additive1">additive&lt;T&gt;</a></code><br>
+ <code>additive1&lt;T&gt;</code></td>
+
+ <td>
+ <ul>
+ <li><code><a href="#addable1">addable&lt;T&gt;</a></code></li>
+
+ <li><code><a href=
+ "#subtractable1">subtractable&lt;T&gt;</a></code></li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code><a name="additive2">additive&lt;T, U&gt;</a></code><br>
+ <code>additive2&lt;T, U&gt;</code></td>
+
+ <td>
+ <ul>
+ <li><code><a href="#addable2">addable&lt;T, U&gt;</a></code></li>
+
+ <li><code><a href="#subtractable2">subtractable&lt;T,
+ U&gt;</a></code></li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code><a name=
+ "multiplicative1">multiplicative&lt;T&gt;</a></code><br>
+ <code>multiplicative1&lt;T&gt;</code></td>
+
+ <td>
+ <ul>
+ <li><code><a href=
+ "#multipliable1">multipliable&lt;T&gt;</a></code></li>
+
+ <li><code><a href=
+ "#dividable1">dividable&lt;T&gt;</a></code></li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code><a name="multiplicative2">multiplicative&lt;T,
+ U&gt;</a></code><br>
+ <code>multiplicative2&lt;T, U&gt;</code></td>
+
+ <td>
+ <ul>
+ <li><code><a href="#multipliable2">multipliable&lt;T,
+ U&gt;</a></code></li>
+
+ <li><code><a href="#dividable2">dividable&lt;T,
+ U&gt;</a></code></li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code><a name=
+ "integer_multiplicative1">integer_multiplicative&lt;T&gt;</a></code><br>
+
+ <code>integer_multiplicative1&lt;T&gt;</code></td>
+
+ <td>
+ <ul>
+ <li><code><a href=
+ "#multiplicative1">multiplicative&lt;T&gt;</a></code></li>
+
+ <li><code><a href="#modable1">modable&lt;T&gt;</a></code></li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code><a name=
+ "integer_multiplicative2">integer_multiplicative&lt;T,
+ U&gt;</a></code><br>
+ <code>integer_multiplicative2&lt;T, U&gt;</code></td>
+
+ <td>
+ <ul>
+ <li><code><a href="#multiplicative2">multiplicative&lt;T,
+ U&gt;</a></code></li>
+
+ <li><code><a href="#modable2">modable&lt;T, U&gt;</a></code></li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code><a name="arithmetic1">arithmetic&lt;T&gt;</a></code><br>
+ <code>arithmetic1&lt;T&gt;</code></td>
+
+ <td>
+ <ul>
+ <li><code><a href="#additive1">additive&lt;T&gt;</a></code></li>
+
+ <li><code><a href=
+ "#multiplicative1">multiplicative&lt;T&gt;</a></code></li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code><a name="arithmetic2">arithmetic&lt;T, U&gt;</a></code><br>
+ <code>arithmetic2&lt;T, U&gt;</code></td>
+
+ <td>
+ <ul>
+ <li><code><a href="#additive2">additive&lt;T,
+ U&gt;</a></code></li>
+
+ <li><code><a href="#multiplicative2">multiplicative&lt;T,
+ U&gt;</a></code></li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code><a name=
+ "integer_arithmetic1">integer_arithmetic&lt;T&gt;</a></code><br>
+ <code>integer_arithmetic1&lt;T&gt;</code></td>
+
+ <td>
+ <ul>
+ <li><code><a href="#additive1">additive&lt;T&gt;</a></code></li>
+
+ <li><code><a href=
+ "#integer_multiplicative1">integer_multiplicative&lt;T&gt;</a></code></li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code><a name="integer_arithmetic2">integer_arithmetic&lt;T,
+ U&gt;</a></code><br>
+ <code>integer_arithmetic2&lt;T, U&gt;</code></td>
+
+ <td>
+ <ul>
+ <li><code><a href="#additive2">additive&lt;T,
+ U&gt;</a></code></li>
+
+ <li><code><a href=
+ "#integer_multiplicative2">integer_multiplicative&lt;T,
+ U&gt;</a></code></li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code><a name="bitwise1">bitwise&lt;T&gt;</a></code><br>
+ <code>bitwise1&lt;T&gt;</code></td>
+
+ <td>
+ <ul>
+ <li><code><a href="#xorable1">xorable&lt;T&gt;</a></code></li>
+
+ <li><code><a href="#andable1">andable&lt;T&gt;</a></code></li>
+
+ <li><code><a href="#orable1">orable&lt;T&gt;</a></code></li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code><a name="bitwise2">bitwise&lt;T, U&gt;</a></code><br>
+ <code>bitwise2&lt;T, U&gt;</code></td>
+
+ <td>
+ <ul>
+ <li><code><a href="#xorable2">xorable&lt;T, U&gt;</a></code></li>
+
+ <li><code><a href="#andable2">andable&lt;T, U&gt;</a></code></li>
+
+ <li><code><a href="#orable2">orable&lt;T, U&gt;</a></code></li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code><a name=
+ "unit_steppable">unit_steppable&lt;T&gt;</a></code></td>
+
+ <td>
+ <ul>
+ <li><code><a href=
+ "#incrementable">incrementable&lt;T&gt;</a></code></li>
+
+ <li><code><a href=
+ "#decrementable">decrementable&lt;T&gt;</a></code></li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code><a name="shiftable1">shiftable&lt;T&gt;</a></code><br>
+ <code>shiftable1&lt;T&gt;</code></td>
+
+ <td>
+ <ul>
+ <li><code><a href=
+ "#left_shiftable1">left_shiftable&lt;T&gt;</a></code></li>
+
+ <li><code><a href=
+ "#right_shiftable1">right_shiftable&lt;T&gt;</a></code></li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code><a name="shiftable2">shiftable&lt;T, U&gt;</a></code><br>
+ <code>shiftable2&lt;T, U&gt;</code></td>
+
+ <td>
+ <ul>
+ <li><code><a href="#left_shiftable2">left_shiftable&lt;T,
+ U&gt;</a></code></li>
+
+ <li><code><a href="#right_shiftable2">right_shiftable&lt;T,
+ U&gt;</a></code></li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code><a name=
+ "ring_operators1">ring_operators&lt;T&gt;</a></code><br>
+ <code>ring_operators1&lt;T&gt;</code></td>
+
+ <td>
+ <ul>
+ <li><code><a href="#additive1">additive&lt;T&gt;</a></code></li>
+
+ <li><code><a href=
+ "#multipliable1">multipliable&lt;T&gt;</a></code></li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code><a name="ring_operators2">ring_operators&lt;T,
+ U&gt;</a></code><br>
+ <code>ring_operators2&lt;T, U&gt;</code></td>
+
+ <td>
+ <ul>
+ <li><code><a href="#additive2">additive&lt;T,
+ U&gt;</a></code></li>
+
+ <li><code><a href="#subtractable2_left">subtractable2_left&lt;T,
+ U&gt;</a></code></li>
+
+ <li><code><a href="#multipliable2">multipliable&lt;T,
+ U&gt;</a></code></li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code><a name=
+ "ordered_ring_operators1">ordered_ring_operators&lt;T&gt;</a></code><br>
+
+ <code>ordered_ring_operators1&lt;T&gt;</code></td>
+
+ <td>
+ <ul>
+ <li><code><a href=
+ "#ring_operators1">ring_operators&lt;T&gt;</a></code></li>
+
+ <li><code><a href=
+ "#totally_ordered1">totally_ordered&lt;T&gt;</a></code></li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code><a name=
+ "ordered_ring_operators2">ordered_ring_operators&lt;T,
+ U&gt;</a></code><br>
+ <code>ordered_ring_operators2&lt;T, U&gt;</code></td>
+
+ <td>
+ <ul>
+ <li><code><a href="#ring_operators2">ring_operators&lt;T,
+ U&gt;</a></code></li>
+
+ <li><code><a href="#totally_ordered2">totally_ordered&lt;T,
+ U&gt;</a></code></li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code><a name=
+ "field_operators1">field_operators&lt;T&gt;</a></code><br>
+ <code>field_operators1&lt;T&gt;</code></td>
+
+ <td>
+ <ul>
+ <li><code><a href=
+ "#ring_operators1">ring_operators&lt;T&gt;</a></code></li>
+
+ <li><code><a href=
+ "#dividable1">dividable&lt;T&gt;</a></code></li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code><a name="field_operators2">field_operators&lt;T,
+ U&gt;</a></code><br>
+ <code>field_operators2&lt;T, U&gt;</code></td>
+
+ <td>
+ <ul>
+ <li><code><a href="#ring_operators2">ring_operators&lt;T,
+ U&gt;</a></code></li>
+
+ <li><code><a href="#dividable2">dividable&lt;T,
+ U&gt;</a></code></li>
+
+ <li><code><a href="#dividable2_left">dividable2_left&lt;T,
+ U&gt;</a></code></li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code><a name=
+ "ordered_field_operators1">ordered_field_operators&lt;T&gt;</a></code><br>
+
+ <code>ordered_field_operators1&lt;T&gt;</code></td>
+
+ <td>
+ <ul>
+ <li><code><a href=
+ "#field_operators1">field_operators&lt;T&gt;</a></code></li>
+
+ <li><code><a href=
+ "#totally_ordered1">totally_ordered&lt;T&gt;</a></code></li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code><a name=
+ "ordered_field_operators2">ordered_field_operators&lt;T,
+ U&gt;</a></code><br>
+ <code>ordered_field_operators2&lt;T, U&gt;</code></td>
+
+ <td>
+ <ul>
+ <li><code><a href="#field_operators2">field_operators&lt;T,
+ U&gt;</a></code></li>
+
+ <li><code><a href="#totally_ordered2">totally_ordered&lt;T,
+ U&gt;</a></code></li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code><a name=
+ "euclidean_ring_operators1">euclidean_ring_operators&lt;T&gt;</a></code><br>
+
+ <code>euclidean_ring_operators1&lt;T&gt;</code></td>
+
+ <td>
+ <ul>
+ <li><code><a href=
+ "#ring_operators1">ring_operators&lt;T&gt;</a></code></li>
+
+ <li><code><a href=
+ "#dividable1">dividable&lt;T&gt;</a></code></li>
+
+ <li><code><a href="#modable1">modable&lt;T&gt;</a></code></li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code><a name=
+ "euclidean_ring_operators2">euclidean_ring_operators&lt;T,
+ U&gt;</a></code><br>
+ <code>euclidean_ring_operators2&lt;T, U&gt;</code></td>
+
+ <td>
+ <ul>
+ <li><code><a href="#ring_operators2">ring_operators&lt;T,
+ U&gt;</a></code></li>
+
+ <li><code><a href="#dividable2">dividable&lt;T,
+ U&gt;</a></code></li>
+
+ <li><code><a href="#dividable2_left">dividable2_left&lt;T,
+ U&gt;</a></code></li>
+
+ <li><code><a href="#modable2">modable&lt;T, U&gt;</a></code></li>
+
+ <li><code><a href="#modable2_left">modable2_left&lt;T,
+ U&gt;</a></code></li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code><a name=
+ "ordered_euclidean_ring_operators1">ordered_euclidean_ring_operators&lt;T&gt;</a></code><br>
+
+ <code>ordered_euclidean_ring_operators1&lt;T&gt;</code></td>
+
+ <td>
+ <ul>
+ <li><code><a href=
+ "#euclidean_ring_operators1">euclidean_ring_operators&lt;T&gt;</a></code></li>
+
+ <li><code><a href=
+ "#totally_ordered1">totally_ordered&lt;T&gt;</a></code></li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code><a name=
+ "ordered_euclidean_ring_operators2">ordered_euclidean_ring_operators&lt;T,
+ U&gt;</a></code><br>
+ <code>ordered_euclidean_ring_operators2&lt;T, U&gt;</code></td>
+
+ <td>
+ <ul>
+ <li><code><a href=
+ "#euclidean_ring_operators2">euclidean_ring_operators&lt;T,
+ U&gt;</a></code></li>
+
+ <li><code><a href="#totally_ordered2">totally_ordered&lt;T,
+ U&gt;</a></code></li>
+ </ul>
+ </td>
+ </tr>
+ </table>
+
+ <h4>Spelling: euclidean vs. euclidian</h4>
+
+ <p>Older versions of the Boost.Operators library used
+ &quot;<code>euclidian</code>&quot;, but it was pointed out that
+ &quot;<code>euclidean</code>&quot; is the more common spelling.
+ To be compatible with older version, the library now supports
+ both spellings.
+ </p>
+
+ <h3><a name="ex_oprs">Example</a> Templates</h3>
+
+ <p>The arithmetic operator class templates <code><a href=
+ "#operators1">operators&lt;&gt;</a></code> and <code><a href=
+ "#operators2">operators2&lt;&gt;</a></code> are examples of
+ non-extensible operator grouping classes. These legacy class templates,
+ from previous versions of the header, cannot be used for <a href=
+ "#chaining">base class chaining</a>.</p>
+
+ <table cellpadding="5" border="1" align="center">
+ <caption>
+ Final Arithmetic Operator Template Classes
+ </caption>
+
+ <tr>
+ <td colspan="2">
+ <table align="center" border="1">
+ <caption>
+ <em>Key</em>
+ </caption>
+
+ <tr>
+ <td><code>T</code>: primary operand type</td>
+
+ <td><code>U</code>: alternate operand type</td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+
+ <tr>
+ <th>Template</th>
+
+ <th>Component Operator Templates</th>
+ </tr>
+
+ <tr>
+ <td><code><a name="operators1">operators&lt;T&gt;</a></code></td>
+
+ <td>
+ <ul>
+ <li><code><a href=
+ "#totally_ordered1">totally_ordered&lt;T&gt;</a></code></li>
+
+ <li><code><a href=
+ "#integer_arithmetic1">integer_arithmetic&lt;T&gt;</a></code></li>
+
+ <li><code><a href="#bitwise1">bitwise&lt;T&gt;</a></code></li>
+
+ <li><code><a href=
+ "#unit_steppable">unit_steppable&lt;T&gt;</a></code></li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code><a name="operators2">operators&lt;T, U&gt;</a></code><br>
+ <code>operators2&lt;T, U&gt;</code></td>
+
+ <td>
+ <ul>
+ <li><code><a href="#totally_ordered2">totally_ordered&lt;T,
+ U&gt;</a></code></li>
+
+ <li><code><a href="#integer_arithmetic2">integer_arithmetic&lt;T,
+ U&gt;</a></code></li>
+
+ <li><code><a href="#bitwise2">bitwise&lt;T, U&gt;</a></code></li>
+ </ul>
+ </td>
+ </tr>
+ </table>
+
+ <h3><a name="a_demo">Arithmetic Operators Demonstration</a> and Test
+ Program</h3>
+
+ <p>The <cite><a href="test/operators_test.cpp">operators_test.cpp</a></cite>
+ program demonstrates the use of the arithmetic operator templates, and
+ can also be used to verify correct operation. Check the compiler status
+ report for the test results with selected platforms.</p>
+
+ <h2><a name="deref">Dereference</a> Operators and Iterator Helpers</h2>
+
+ <p>The <a href="#iterator">iterator helper</a> templates ease the task of
+ creating a custom iterator. Similar to arithmetic types, a complete
+ iterator has many operators that are "redundant" and can be implemented
+ in terms of the core set of operators.</p>
+
+ <p>The <a href="#dereference">dereference operators</a> were motivated by
+ the <a href="#iterator">iterator helpers</a>, but are often useful in
+ non-iterator contexts as well. Many of the redundant iterator operators
+ are also arithmetic operators, so the iterator helper classes borrow many
+ of the operators defined above. In fact, only two new operators need to
+ be defined (the pointer-to-member <code>operator-&gt;</code> and the
+ subscript <code>operator[]</code>)!</p>
+
+ <p>The requirements for the types used to instantiate the dereference
+ operators are specified in terms of expressions which must be valid and
+ their return type. The composite operator templates list their component
+ templates, which the instantiating type must support, and possibly other
+ requirements.</p>
+
+ <h3><a name="dereference">Dereference</a> Operators</h3>
+
+ <p>All the dereference operator templates in this table accept an
+ optional template parameter (not shown) to be used for <a href=
+ "#chaining">base class chaining</a>.</p>
+
+ <table cellpadding="5" border="1" align="center">
+ <caption>
+ Dereference Operator Template Classes
+ </caption>
+
+ <tr>
+ <td colspan="3">
+ <table align="center" border="1">
+ <caption>
+ <em>Key</em>
+ </caption>
+
+ <tr>
+ <td><code>T</code>: operand type</td>
+
+ <td><code>P</code>: <code>pointer</code> type</td>
+ </tr>
+
+ <tr>
+ <td><code>D</code>: <code>difference_type</code></td>
+
+ <td><code>R</code>: <code>reference</code> type</td>
+ </tr>
+
+ <tr>
+ <td><code>i</code>: object of type <code>T</code> (an
+ iterator)</td>
+
+ <td><code>n</code>: object of type <code>D</code> (an
+ index)</td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+
+ <tr>
+ <th>Template</th>
+
+ <th>Supplied Operations</th>
+
+ <th>Requirements</th>
+ </tr>
+
+ <tr>
+ <td><code><a name="dereferenceable">dereferenceable&lt;T,
+ P&gt;</a></code></td>
+
+ <td><code>P operator-&gt;() const</code></td>
+
+ <td><code>*i</code>. Address of the returned value convertible
+ to <code>P</code>.</td>
+ </tr>
+
+ <tr>
+ <td><code><a name="indexable">indexable&lt;T, D,
+ R&gt;</a></code></td>
+
+ <td><code>R operator[](D n) const</code></td>
+
+ <td><code>*(i&nbsp;+&nbsp;n)</code>. Return of type
+ <code>R</code>.</td>
+ </tr>
+ </table>
+
+ <h3><a name="grpd_iter_oprs">Grouped Iterator Operators</a></h3>
+
+ <p>There are five iterator operator class templates, each for a different
+ category of iterator. The following table shows the operator groups for
+ any category that a custom iterator could define. These class templates
+ have an additional optional template parameter <code>B</code>, which is
+ not shown, to support <a href="#chaining">base class chaining</a>.</p>
+
+ <table cellpadding="5" border="1" align="center">
+ <caption>
+ Iterator Operator Class Templates
+ </caption>
+
+ <tr>
+ <td colspan="2">
+ <table align="center" border="1">
+ <caption>
+ <em>Key</em>
+ </caption>
+
+ <tr>
+ <td><code>T</code>: operand type</td>
+
+ <td><code>P</code>: <code>pointer</code> type</td>
+ </tr>
+
+ <tr>
+ <td><code>D</code>: <code>difference_type</code></td>
+
+ <td><code>R</code>: <code>reference</code> type</td>
+ </tr>
+
+ <tr>
+ <td><code>V</code>: <code>value_type</code></td>
+
+ <td>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+
+ <tr>
+ <th>Template</th>
+
+ <th>Component Operator Templates</th>
+ </tr>
+
+ <tr>
+ <td><code><a name="input_iteratable">input_iteratable&lt;T,
+ P&gt;</a></code></td>
+
+ <td>
+ <ul>
+ <li><code><a href=
+ "#equality_comparable1">equality_comparable&lt;T&gt;</a></code></li>
+
+ <li><code><a href=
+ "#incrementable">incrementable&lt;T&gt;</a></code></li>
+
+ <li><code><a href="#dereferenceable">dereferenceable&lt;T,
+ P&gt;</a></code></li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code><a name=
+ "output_iteratable">output_iteratable&lt;T&gt;</a></code></td>
+
+ <td>
+ <ul>
+ <li><code><a href=
+ "#incrementable">incrementable&lt;T&gt;</a></code></li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code><a name="forward_iteratable">forward_iteratable&lt;T,
+ P&gt;</a></code></td>
+
+ <td>
+ <ul>
+ <li><code><a href="#input_iteratable">input_iteratable&lt;T,
+ P&gt;</a></code></li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code><a name=
+ "bidirectional_iteratable">bidirectional_iteratable&lt;T,
+ P&gt;</a></code></td>
+
+ <td>
+ <ul>
+ <li><code><a href="#forward_iteratable">forward_iteratable&lt;T,
+ P&gt;</a></code></li>
+
+ <li><code><a href=
+ "#decrementable">decrementable&lt;T&gt;</a></code></li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code><a name=
+ "random_access_iteratable">random_access_iteratable&lt;T, P, D,
+ R&gt;</a></code></td>
+
+ <td>
+ <ul>
+ <li><code><a href=
+ "#bidirectional_iteratable">bidirectional_iteratable&lt;T,
+ P&gt;</a></code></li>
+
+ <li><code><a href=
+ "#totally_ordered1">totally_ordered&lt;T&gt;</a></code></li>
+
+ <li><code><a href="#additive2">additive&lt;T,
+ D&gt;</a></code></li>
+
+ <li><code><a href="#indexable">indexable&lt;T, D,
+ R&gt;</a></code></li>
+ </ul>
+ </td>
+ </tr>
+ </table>
+
+ <h3><a name="iterator">Iterator</a> Helpers</h3>
+
+ <p>There are also five iterator helper class templates, each
+ corresponding to a different iterator category. These classes cannot be
+ used for <a href="#chaining">base class chaining</a>. The following
+ summaries show that these class templates supply both the iterator
+ operators from the <a href="#grpd_iter_oprs">iterator operator class
+ templates</a> and the iterator typedef's required by the C++ standard
+ (<code>iterator_category</code>, <code>value_type</code>,
+ <i>etc.</i>).</p>
+
+ <table cellpadding="5" border="1" align="center">
+ <caption>
+ Iterator Helper Class Templates
+ </caption>
+
+ <tr>
+ <td colspan="2">
+ <table align="center" border="1">
+ <caption>
+ <em>Key</em>
+ </caption>
+
+ <tr>
+ <td><code>T</code>: operand type</td>
+
+ <td><code>P</code>: <code>pointer</code> type</td>
+ </tr>
+
+ <tr>
+ <td><code>D</code>: <code>difference_type</code></td>
+
+ <td><code>R</code>: <code>reference</code> type</td>
+ </tr>
+
+ <tr>
+ <td><code>V</code>: <code>value_type</code></td>
+
+ <td><code>x1, x2</code>: objects of type <code>T</code></td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+
+ <tr>
+ <th>Template</th>
+
+ <th>Operations &amp; Requirements</th>
+ </tr>
+
+ <tr valign="baseline">
+ <td><code><a name="input_iterator_helper">input_iterator_helper&lt;T,
+ V, D, P, R&gt;</a></code></td>
+
+ <td>
+ Supports the operations and has the requirements of
+
+ <ul>
+ <li><code><a href="#input_iteratable">input_iteratable&lt;T,
+ P&gt;</a></code></li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr valign="baseline">
+ <td><code><a name=
+ "output_iterator_helper">output_iterator_helper&lt;T&gt;</a></code></td>
+
+ <td>
+ Supports the operations and has the requirements of
+
+ <ul>
+ <li><code><a href=
+ "#output_iteratable">output_iteratable&lt;T&gt;</a></code></li>
+ </ul>
+ See also [<a href="#1">1</a>], [<a href="#2">2</a>].
+ </td>
+ </tr>
+
+ <tr valign="baseline">
+ <td><code><a name=
+ "forward_iterator_helper">forward_iterator_helper&lt;T, V, D, P,
+ R&gt;</a></code></td>
+
+ <td>
+ Supports the operations and has the requirements of
+
+ <ul>
+ <li><code><a href="#forward_iteratable">forward_iteratable&lt;T,
+ P&gt;</a></code></li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr valign="baseline">
+ <td><code><a name=
+ "bidirectional_iterator_helper">bidirectional_iterator_helper&lt;T,
+ V, D, P, R&gt;</a></code></td>
+
+ <td>
+ Supports the operations and has the requirements of
+
+ <ul>
+ <li><code><a href=
+ "#bidirectional_iteratable">bidirectional_iteratable&lt;T,
+ P&gt;</a></code></li>
+ </ul>
+ </td>
+ </tr>
+
+ <tr valign="baseline">
+ <td><code><a name=
+ "random_access_iterator_helper">random_access_iterator_helper&lt;T,
+ V, D, P, R&gt;</a></code></td>
+
+ <td>
+ Supports the operations and has the requirements of
+
+ <ul>
+ <li><code><a href=
+ "#random_access_iteratable">random_access_iteratable&lt;T, P, D,
+ R&gt;</a></code></li>
+ </ul>
+ To satisfy <cite><a href=
+ "http://www.sgi.com/tech/stl/RandomAccessIterator.html">RandomAccessIterator</a></cite>,
+ <code>x1 - x2</code> with return convertible to <code>D</code> is
+ also required.
+ </td>
+ </tr>
+ </table>
+
+ <h4><a name="iterator_helpers_notes">Iterator Helper Notes</a></h4>
+
+ <p><a name="1">[1]</a> Unlike other iterator helpers templates,
+ <code>output_iterator_helper</code> takes only one template parameter -
+ the type of its target class. Although to some it might seem like an
+ unnecessary restriction, the standard requires
+ <code>difference_type</code> and <code>value_type</code> of any output
+ iterator to be <code>void</code> (24.3.1 [lib.iterator.traits]), and
+ <code>output_iterator_helper</code> template respects this requirement.
+ Also, output iterators in the standard have void <code>pointer</code> and
+ <code>reference</code> types, so the <code>output_iterator_helper</code>
+ does the same.</p>
+
+ <p><a name="2">[2]</a> As self-proxying is the easiest and most common
+ way to implement output iterators (see, for example, insert [24.4.2] and
+ stream iterators [24.5] in the standard library),
+ <code>output_iterator_helper</code> supports the idiom by defining
+ <code>operator*</code> and <code>operator++</code> member functions which
+ just return a non-const reference to the iterator itself. Support for
+ self-proxying allows us, in many cases, to reduce the task of writing an
+ output iterator to writing just two member functions - an appropriate
+ constructor and a copy-assignment operator. For example, here is a
+ possible implementation of <code><a href=
+ "../iterator/doc/function_output_iterator.html">boost::function_output_iterator</a></code>
+ adaptor:</p>
+<pre>
+template&lt;class UnaryFunction&gt;
+struct function_output_iterator
+ : boost::output_iterator_helper&lt; function_output_iterator&lt;UnaryFunction&gt; &gt;
+{
+ explicit function_output_iterator(UnaryFunction const&amp; f = UnaryFunction())
+ : func(f) {}
+
+ template&lt;typename T&gt;
+ function_output_iterator&amp; operator=(T const&amp; value)
+ {
+ this-&gt;func(value);
+ return *this;
+ }
+
+ private:
+ UnaryFunction func;
+};
+</pre>
+
+ <p>Note that support for self-proxying does not prevent you from using
+ <code>output_iterator_helper</code> to ease any other, different kind of
+ output iterator's implementation. If
+ <code>output_iterator_helper</code>'s target type provides its own
+ definition of <code>operator*</code> or/and <code>operator++</code>, then
+ these operators will get used and the ones supplied by
+ <code>output_iterator_helper</code> will never be instantiated.</p>
+
+ <h3><a name="i_demo">Iterator Demonstration</a> and Test Program</h3>
+
+ <p>The <cite><a href="test/iterators_test.cpp">iterators_test.cpp</a></cite>
+ program demonstrates the use of the iterator templates, and can also be
+ used to verify correct operation. The following is the custom iterator
+ defined in the test program. It demonstrates a correct (though trivial)
+ implementation of the core operations that must be defined in order for
+ the iterator helpers to "fill in" the rest of the iterator
+ operations.</p>
+
+ <blockquote>
+<pre>
+template &lt;class T, class R, class P&gt;
+struct test_iter
+ : public boost::random_access_iterator_helper&lt;
+ test_iter&lt;T,R,P&gt;, T, std::ptrdiff_t, P, R&gt;
+{
+ typedef test_iter self;
+ typedef R Reference;
+ typedef std::ptrdiff_t Distance;
+
+public:
+ explicit test_iter(T* i =0);
+ test_iter(const self&amp; x);
+ self&amp; operator=(const self&amp; x);
+ Reference operator*() const;
+ self&amp; operator++();
+ self&amp; operator--();
+ self&amp; operator+=(Distance n);
+ self&amp; operator-=(Distance n);
+ bool operator==(const self&amp; x) const;
+ bool operator&lt;(const self&amp; x) const;
+ friend Distance operator-(const self&amp; x, const self&amp; y);
+};
+</pre>
+ </blockquote>
+
+ <p>Check the <a href="http://www.boost.org/development/testing.html">compiler status
+ report</a> for the test results with selected platforms.</p>
+ <hr>
+
+ <h2><a name="contributors">Contributors</a></h2>
+
+ <dl>
+ <dt><a href="http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a></dt>
+
+ <dd>Started the library and contributed the arithmetic operators in
+ <cite><a href=
+ "../../boost/operators.hpp">boost/operators.hpp</a></cite>.</dd>
+
+ <dt><a href="http://www.boost.org/people/jeremy_siek.htm">Jeremy Siek</a></dt>
+
+ <dd>Contributed the <a href="#deref">dereference operators and iterator
+ helpers</a> in <cite><a href=
+ "../../boost/operators.hpp">boost/operators.hpp</a></cite>. Also
+ contributed <cite><a href=
+ "iterators_test.cpp">iterators_test.cpp</a></cite>.</dd>
+
+ <dt><a href="http://www.boost.org/people/aleksey_gurtovoy.htm">Aleksey
+ Gurtovoy</a></dt>
+
+ <dd>Contributed the code to support <a href="#chaining">base class
+ chaining</a> while remaining backward-compatible with old versions of
+ the library.</dd>
+
+ <dt><a href="http://www.boost.org/people/beman_dawes.html">Beman Dawes</a></dt>
+
+ <dd>Contributed <cite><a href=
+ "test/operators_test.cpp">operators_test.cpp</a></cite>.</dd>
+
+ <dt><a href="http://www.boost.org/people/daryle_walker.html">Daryle Walker</a></dt>
+
+ <dd>Contributed classes for the shift operators, equivalence, partial
+ ordering, and arithmetic conversions. Added the grouped operator
+ classes. Added helper classes for input and output iterators.</dd>
+
+ <dt>Helmut Zeisel</dt>
+
+ <dd>Contributed the 'left' operators and added some grouped operator
+ classes.</dd>
+
+ <dt>Daniel Frey</dt>
+
+ <dd>Contributed the NRVO-friendly and symmetric implementation of
+ arithmetic operators.</dd>
+
+ </dl>
+
+ <h2>Note for Users of <a name="old_lib_note">Older Versions</a></h2>
+
+ <p>The <a href="#chaining">changes in the library interface and
+ recommended usage</a> were motivated by some practical issues described
+ below. The new version of the library is still backward-compatible with
+ the former one (so you're not <em>forced</em> change any existing code),
+ but the old usage is deprecated. Though it was arguably simpler and more
+ intuitive than using <a href="#chaining">base class chaining</a>, it has
+ been discovered that the old practice of deriving from multiple operator
+ templates can cause the resulting classes to be much larger than they
+ should be. Most modern C++ compilers significantly bloat the size of
+ classes derived from multiple empty base classes, even though the base
+ classes themselves have no state. For instance, the size of
+ <code>point&lt;int&gt;</code> from the <a href="#example">example</a>
+ above was 12-24 bytes on various compilers for the Win32 platform,
+ instead of the expected 8 bytes.</p>
+
+ <p>Strictly speaking, it was not the library's fault--the language rules
+ allow the compiler to apply the empty base class optimization in that
+ situation. In principle an arbitrary number of empty base classes can be
+ allocated at the same offset, provided that none of them have a common
+ ancestor (see section 10.5 [class.derived] paragraph 5 of the standard).
+ But the language definition also doesn't <em>require</em> implementations
+ to do the optimization, and few if any of today's compilers implement it
+ when multiple inheritance is involved. What's worse, it is very unlikely
+ that implementors will adopt it as a future enhancement to existing
+ compilers, because it would break binary compatibility between code
+ generated by two different versions of the same compiler. As Matt Austern
+ said, "One of the few times when you have the freedom to do this sort of
+ thing is when you're targeting a new architecture...". On the other hand,
+ many common compilers will use the empty base optimization for single
+ inheritance hierarchies.</p>
+
+ <p>Given the importance of the issue for the users of the library (which
+ aims to be useful for writing light-weight classes like
+ <code>MyInt</code> or <code>point&lt;&gt;</code>), and the forces
+ described above, we decided to change the library interface so that the
+ object size bloat could be eliminated even on compilers that support only
+ the simplest form of the empty base class optimization. The current
+ library interface is the result of those changes. Though the new usage is
+ a bit more complicated than the old one, we think it's worth it to make
+ the library more useful in real world. Alexy Gurtovoy contributed the
+ code which supports the new usage idiom while allowing the library remain
+ backward-compatible.</p>
+ <hr>
+
+ <p>Revised: 7 Aug 2008</p>
+
+ <p>Copyright &copy; Beman Dawes, David Abrahams, 1999-2001.</p>
+ <p>Copyright &copy; Daniel Frey, 2002-2009.</p>
+ <p>Use, modification, and distribution is subject to the Boost Software
+ License, Version 1.0. (See accompanying file
+ <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy at
+ <a href="http://www.boost.org/LICENSE_1_0.txt">
+ www.boost.org/LICENSE_1_0.txt</a>)</p>
+ </body>
+</html>
+
diff --git a/src/boost/libs/utility/sublibs b/src/boost/libs/utility/sublibs
new file mode 100644
index 000000000..721d7c4a9
--- /dev/null
+++ b/src/boost/libs/utility/sublibs
@@ -0,0 +1 @@
+The existance of this file tells the regression reporting programs that the directory contains sub-directories which are libraries. \ No newline at end of file
diff --git a/src/boost/libs/utility/test/Jamfile.v2 b/src/boost/libs/utility/test/Jamfile.v2
new file mode 100644
index 000000000..739edc0de
--- /dev/null
+++ b/src/boost/libs/utility/test/Jamfile.v2
@@ -0,0 +1,44 @@
+# Copyright David Abrahams 2003.
+
+# Distributed under the Boost Software License, Version 1.0.
+# See http://www.boost.org/LICENSE_1_0.txt
+
+# For more information, see http://www.boost.org/
+
+# bring in rules for testing
+import testing ;
+
+run base_from_member_test.cpp ;
+run base_from_member_ref_test.cpp ;
+
+run binary_test.cpp ;
+
+run call_traits_test.cpp : -u ;
+
+run compressed_pair_test.cpp ;
+run compressed_pair_final_test.cpp ;
+
+run iterators_test.cpp ;
+
+run operators_test.cpp ;
+
+compile result_of_test.cpp ;
+
+# compile-fail string_ref_from_rvalue.cpp ;
+run string_ref_test1.cpp ;
+run string_ref_test2.cpp ;
+run string_ref_test_io.cpp ;
+# compile-fail string_view_from_rvalue.cpp ;
+compile string_view_constexpr_test1.cpp ;
+run string_view_test1.cpp ;
+run string_view_test2.cpp ;
+run string_view_test_io.cpp ;
+
+run value_init_test.cpp ;
+run value_init_workaround_test.cpp ;
+run initialized_test.cpp ;
+compile-fail value_init_test_fail1.cpp ;
+compile-fail value_init_test_fail2.cpp ;
+compile-fail value_init_test_fail3.cpp ;
+compile-fail initialized_test_fail1.cpp ;
+compile-fail initialized_test_fail2.cpp ;
diff --git a/src/boost/libs/utility/test/base_from_member_ref_test.cpp b/src/boost/libs/utility/test/base_from_member_ref_test.cpp
new file mode 100644
index 000000000..52f9b8704
--- /dev/null
+++ b/src/boost/libs/utility/test/base_from_member_ref_test.cpp
@@ -0,0 +1,29 @@
+//
+// Test that a base_from_member<T&> can be properly constructed
+//
+// Copyright 2014 Agustin Berge
+//
+// Distributed under the Boost Software License, Version 1.0.
+// See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt
+//
+
+#include <boost/utility/base_from_member.hpp>
+
+#include <boost/core/lightweight_test.hpp>
+
+struct foo : boost::base_from_member<int&>
+{
+ explicit foo(int& ref) : boost::base_from_member<int&>(ref)
+ {
+ BOOST_TEST(&member == &ref);
+ }
+};
+
+int main()
+{
+ int i = 0;
+ foo f(i);
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/utility/test/base_from_member_test.cpp b/src/boost/libs/utility/test/base_from_member_test.cpp
new file mode 100644
index 000000000..685c6387a
--- /dev/null
+++ b/src/boost/libs/utility/test/base_from_member_test.cpp
@@ -0,0 +1,593 @@
+// Boost test program for base-from-member class templates -----------------//
+
+// Copyright 2001, 2003 Daryle Walker. Use, modification, and distribution are
+// subject to the Boost Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)
+
+// See <http://www.boost.org/libs/utility/> for the library's home page.
+
+// Revision History
+// 14 Jun 2003 Adjusted code for Boost.Test changes (Daryle Walker)
+// 29 Aug 2001 Initial Version (Daryle Walker)
+
+#include <boost/core/lightweight_test.hpp>
+
+#include <boost/config.hpp> // for BOOST_NO_MEMBER_TEMPLATES
+#include <boost/noncopyable.hpp> // for boost::noncopyable
+
+#include <boost/utility/base_from_member.hpp> // for boost::base_from_member
+
+#include <functional> // for std::less
+#include <iostream> // for std::cout (std::ostream, std::endl indirectly)
+#include <set> // for std::set
+#include <typeinfo> // for std::type_info
+#include <utility> // for std::pair, std::make_pair
+#include <vector> // for std::vector
+
+
+// Control if extra information is printed
+#ifndef CONTROL_EXTRA_PRINTING
+#define CONTROL_EXTRA_PRINTING 1
+#endif
+
+
+// A (sub)object can be identified by its memory location and its type.
+// Both are needed since an object can start at the same place as its
+// first base class subobject and/or contained subobject.
+typedef std::pair< void *, std::type_info const * > object_id;
+
+// Object IDs need to be printed
+std::ostream & operator <<( std::ostream &os, object_id const &oi );
+
+// A way to generate an object ID
+template < typename T >
+ object_id identify( T &obj );
+
+// A custom comparison type is needed
+struct object_id_compare
+{
+ bool operator ()( object_id const &a, object_id const &b ) const;
+
+}; // object_id_compare
+
+// A singleton of this type coordinates the acknowledgements
+// of objects being created and used.
+class object_registrar
+ : private boost::noncopyable
+{
+public:
+
+ #ifndef BOOST_NO_MEMBER_TEMPLATES
+ template < typename T >
+ void register_object( T &obj )
+ { this->register_object_imp( identify(obj) ); }
+ template < typename T, typename U >
+ void register_use( T &owner, U &owned )
+ { this->register_use_imp( identify(owner), identify(owned) ); }
+ template < typename T, typename U >
+ void unregister_use( T &owner, U &owned )
+ { this->unregister_use_imp( identify(owner), identify(owned) ); }
+ template < typename T >
+ void unregister_object( T &obj )
+ { this->unregister_object_imp( identify(obj) ); }
+ #endif
+
+ void register_object_imp( object_id obj );
+ void register_use_imp( object_id owner, object_id owned );
+ void unregister_use_imp( object_id owner, object_id owned );
+ void unregister_object_imp( object_id obj );
+
+ typedef std::set<object_id, object_id_compare> set_type;
+
+ typedef std::vector<object_id> error_record_type;
+ typedef std::vector< std::pair<object_id, object_id> > error_pair_type;
+
+ set_type db_;
+
+ error_pair_type defrauders_in_, defrauders_out_;
+ error_record_type overeager_, overkilled_;
+
+}; // object_registrar
+
+// A sample type to be used by containing types
+class base_or_member
+{
+public:
+ explicit base_or_member( int x = 1, double y = -0.25 );
+ ~base_or_member();
+
+}; // base_or_member
+
+// A sample type that uses base_or_member, used
+// as a base for the main demonstration classes
+class base_class
+{
+public:
+ explicit base_class( base_or_member &x, base_or_member *y = 0,
+ base_or_member *z = 0 );
+
+ ~base_class();
+
+private:
+ base_or_member *x_, *y_, *z_;
+
+}; // base_class
+
+// This bad class demonstrates the direct method of a base class needing
+// to be initialized by a member. This is improper since the member
+// isn't initialized until after the base class.
+class bad_class
+ : public base_class
+{
+public:
+ bad_class();
+ ~bad_class();
+
+private:
+ base_or_member x_;
+
+}; // bad_class
+
+// The first good class demonstrates the correct way to initialize a
+// base class with a member. The member is changed to another base
+// class, one that is initialized before the base that needs it.
+class good_class_1
+ : private boost::base_from_member<base_or_member>
+ , public base_class
+{
+ typedef boost::base_from_member<base_or_member> pbase_type;
+ typedef base_class base_type;
+
+public:
+ good_class_1();
+ ~good_class_1();
+
+}; // good_class_1
+
+// The second good class also demonstrates the correct way to initialize
+// base classes with other subobjects. This class uses the other helpers
+// in the library, and shows the technique of using two base subobjects
+// of the "same" type.
+class good_class_2
+ : private boost::base_from_member<base_or_member, 0>
+ , private boost::base_from_member<base_or_member, 1>
+ , private boost::base_from_member<base_or_member, 2>
+ , public base_class
+{
+ typedef boost::base_from_member<base_or_member, 0> pbase_type0;
+ typedef boost::base_from_member<base_or_member, 1> pbase_type1;
+ typedef boost::base_from_member<base_or_member, 2> pbase_type2;
+ typedef base_class base_type;
+
+public:
+ good_class_2();
+ ~good_class_2();
+
+}; // good_class_2
+
+// Declare/define the single object registrar
+object_registrar obj_reg;
+
+
+// Main functionality
+int
+main()
+{
+ BOOST_TEST( obj_reg.db_.empty() );
+ BOOST_TEST( obj_reg.defrauders_in_.empty() );
+ BOOST_TEST( obj_reg.defrauders_out_.empty() );
+ BOOST_TEST( obj_reg.overeager_.empty() );
+ BOOST_TEST( obj_reg.overkilled_.empty() );
+
+ // Make a separate block to examine pre- and post-effects
+ {
+ using std::cout;
+ using std::endl;
+
+ bad_class bc;
+ BOOST_TEST( obj_reg.db_.size() == 3 );
+ BOOST_TEST( obj_reg.defrauders_in_.size() == 1 );
+
+ good_class_1 gc1;
+ BOOST_TEST( obj_reg.db_.size() == 6 );
+ BOOST_TEST( obj_reg.defrauders_in_.size() == 1 );
+
+ good_class_2 gc2;
+ BOOST_TEST( obj_reg.db_.size() == 11 );
+ BOOST_TEST( obj_reg.defrauders_in_.size() == 1 );
+
+ BOOST_TEST( obj_reg.defrauders_out_.empty() );
+ BOOST_TEST( obj_reg.overeager_.empty() );
+ BOOST_TEST( obj_reg.overkilled_.empty() );
+
+ // Getting the addresses of the objects ensure
+ // that they're used, and not optimized away.
+ cout << "Object 'bc' is at " << &bc << '.' << endl;
+ cout << "Object 'gc1' is at " << &gc1 << '.' << endl;
+ cout << "Object 'gc2' is at " << &gc2 << '.' << endl;
+ }
+
+ BOOST_TEST( obj_reg.db_.empty() );
+ BOOST_TEST( obj_reg.defrauders_in_.size() == 1 );
+ BOOST_TEST( obj_reg.defrauders_out_.size() == 1 );
+ BOOST_TEST( obj_reg.overeager_.empty() );
+ BOOST_TEST( obj_reg.overkilled_.empty() );
+
+ return boost::report_errors();
+}
+
+
+// Print an object's ID
+std::ostream &
+operator <<
+(
+ std::ostream & os,
+ object_id const & oi
+)
+{
+ // I had an std::ostringstream to help, but I did not need it since
+ // the program never screws around with formatting. Worse, using
+ // std::ostringstream is an issue with some compilers.
+
+ return os << '[' << ( oi.second ? oi.second->name() : "NOTHING" )
+ << " at " << oi.first << ']';
+}
+
+// Get an object ID given an object
+template < typename T >
+inline
+object_id
+identify
+(
+ T & obj
+)
+{
+ return std::make_pair( static_cast<void *>(&obj), &(typeid( obj )) );
+}
+
+// Compare two object IDs
+bool
+object_id_compare::operator ()
+(
+ object_id const & a,
+ object_id const & b
+) const
+{
+ std::less<void *> vp_cmp;
+ if ( vp_cmp(a.first, b.first) )
+ {
+ return true;
+ }
+ else if ( vp_cmp(b.first, a.first) )
+ {
+ return false;
+ }
+ else
+ {
+ // object pointers are equal, compare the types
+ if ( a.second == b.second )
+ {
+ return false;
+ }
+ else if ( !a.second )
+ {
+ return true; // NULL preceeds anything else
+ }
+ else if ( !b.second )
+ {
+ return false; // NULL preceeds anything else
+ }
+ else
+ {
+ return a.second->before( *b.second ) != 0;
+ }
+ }
+}
+
+// Let an object register its existence
+void
+object_registrar::register_object_imp
+(
+ object_id obj
+)
+{
+ if ( db_.count(obj) <= 0 )
+ {
+ db_.insert( obj );
+
+ #if CONTROL_EXTRA_PRINTING
+ std::cout << "Registered " << obj << '.' << std::endl;
+ #endif
+ }
+ else
+ {
+ overeager_.push_back( obj );
+
+ #if CONTROL_EXTRA_PRINTING
+ std::cout << "Attempted to register a non-existant " << obj
+ << '.' << std::endl;
+ #endif
+ }
+}
+
+// Let an object register its use of another object
+void
+object_registrar::register_use_imp
+(
+ object_id owner,
+ object_id owned
+)
+{
+ if ( db_.count(owned) > 0 )
+ {
+ // We don't care to record usage registrations
+ }
+ else
+ {
+ defrauders_in_.push_back( std::make_pair(owner, owned) );
+
+ #if CONTROL_EXTRA_PRINTING
+ std::cout << "Attempted to own a non-existant " << owned
+ << " by " << owner << '.' << std::endl;
+ #endif
+ }
+}
+
+// Let an object un-register its use of another object
+void
+object_registrar::unregister_use_imp
+(
+ object_id owner,
+ object_id owned
+)
+{
+ if ( db_.count(owned) > 0 )
+ {
+ // We don't care to record usage un-registrations
+ }
+ else
+ {
+ defrauders_out_.push_back( std::make_pair(owner, owned) );
+
+ #if CONTROL_EXTRA_PRINTING
+ std::cout << "Attempted to disown a non-existant " << owned
+ << " by " << owner << '.' << std::endl;
+ #endif
+ }
+}
+
+// Let an object un-register its existence
+void
+object_registrar::unregister_object_imp
+(
+ object_id obj
+)
+{
+ set_type::iterator const i = db_.find( obj );
+
+ if ( i != db_.end() )
+ {
+ db_.erase( i );
+
+ #if CONTROL_EXTRA_PRINTING
+ std::cout << "Unregistered " << obj << '.' << std::endl;
+ #endif
+ }
+ else
+ {
+ overkilled_.push_back( obj );
+
+ #if CONTROL_EXTRA_PRINTING
+ std::cout << "Attempted to unregister a non-existant " << obj
+ << '.' << std::endl;
+ #endif
+ }
+}
+
+// Macros to abstract the registration of objects
+#ifndef BOOST_NO_MEMBER_TEMPLATES
+#define PRIVATE_REGISTER_BIRTH(o) obj_reg.register_object( (o) )
+#define PRIVATE_REGISTER_DEATH(o) obj_reg.unregister_object( (o) )
+#define PRIVATE_REGISTER_USE(o, w) obj_reg.register_use( (o), (w) )
+#define PRIVATE_UNREGISTER_USE(o, w) obj_reg.unregister_use( (o), (w) )
+#else
+#define PRIVATE_REGISTER_BIRTH(o) obj_reg.register_object_imp( \
+ identify((o)) )
+#define PRIVATE_REGISTER_DEATH(o) obj_reg.unregister_object_imp( \
+ identify((o)) )
+#define PRIVATE_REGISTER_USE(o, w) obj_reg.register_use_imp( identify((o)), \
+ identify((w)) )
+#define PRIVATE_UNREGISTER_USE(o, w) obj_reg.unregister_use_imp( \
+ identify((o)), identify((w)) )
+#endif
+
+// Create a base_or_member, with arguments to simulate member initializations
+base_or_member::base_or_member
+(
+ int x, // = 1
+ double y // = -0.25
+)
+{
+ PRIVATE_REGISTER_BIRTH( *this );
+
+ #if CONTROL_EXTRA_PRINTING
+ std::cout << "\tMy x-factor is " << x << " and my y-factor is " << y
+ << '.' << std::endl;
+ #endif
+}
+
+// Destroy a base_or_member
+inline
+base_or_member::~base_or_member
+(
+)
+{
+ PRIVATE_REGISTER_DEATH( *this );
+}
+
+// Create a base_class, registering any objects used
+base_class::base_class
+(
+ base_or_member & x,
+ base_or_member * y, // = 0
+ base_or_member * z // = 0
+)
+ : x_( &x ), y_( y ), z_( z )
+{
+ PRIVATE_REGISTER_BIRTH( *this );
+
+ #if CONTROL_EXTRA_PRINTING
+ std::cout << "\tMy x-factor is " << x_;
+ #endif
+
+ PRIVATE_REGISTER_USE( *this, *x_ );
+
+ if ( y_ )
+ {
+ #if CONTROL_EXTRA_PRINTING
+ std::cout << ", my y-factor is " << y_;
+ #endif
+
+ PRIVATE_REGISTER_USE( *this, *y_ );
+ }
+
+ if ( z_ )
+ {
+ #if CONTROL_EXTRA_PRINTING
+ std::cout << ", my z-factor is " << z_;
+ #endif
+
+ PRIVATE_REGISTER_USE( *this, *z_ );
+ }
+
+ #if CONTROL_EXTRA_PRINTING
+ std::cout << '.' << std::endl;
+ #endif
+}
+
+// Destroy a base_class, unregistering the objects it uses
+base_class::~base_class
+(
+)
+{
+ PRIVATE_REGISTER_DEATH( *this );
+
+ #if CONTROL_EXTRA_PRINTING
+ std::cout << "\tMy x-factor was " << x_;
+ #endif
+
+ PRIVATE_UNREGISTER_USE( *this, *x_ );
+
+ if ( y_ )
+ {
+ #if CONTROL_EXTRA_PRINTING
+ std::cout << ", my y-factor was " << y_;
+ #endif
+
+ PRIVATE_UNREGISTER_USE( *this, *y_ );
+ }
+
+ if ( z_ )
+ {
+ #if CONTROL_EXTRA_PRINTING
+ std::cout << ", my z-factor was " << z_;
+ #endif
+
+ PRIVATE_UNREGISTER_USE( *this, *z_ );
+ }
+
+ #if CONTROL_EXTRA_PRINTING
+ std::cout << '.' << std::endl;
+ #endif
+}
+
+// Create a bad_class, noting the improper construction order
+bad_class::bad_class
+(
+)
+ : x_( -7, 16.75 ), base_class( x_ ) // this order doesn't matter
+{
+ PRIVATE_REGISTER_BIRTH( *this );
+
+ #if CONTROL_EXTRA_PRINTING
+ std::cout << "\tMy factor is at " << &x_
+ << " and my base is at " << static_cast<base_class *>(this) << '.'
+ << std::endl;
+ #endif
+}
+
+// Destroy a bad_class, noting the improper destruction order
+bad_class::~bad_class
+(
+)
+{
+ PRIVATE_REGISTER_DEATH( *this );
+
+ #if CONTROL_EXTRA_PRINTING
+ std::cout << "\tMy factor was at " << &x_
+ << " and my base was at " << static_cast<base_class *>(this)
+ << '.' << std::endl;
+ #endif
+}
+
+// Create a good_class_1, noting the proper construction order
+good_class_1::good_class_1
+(
+)
+ : pbase_type( 8 ), base_type( member )
+{
+ PRIVATE_REGISTER_BIRTH( *this );
+
+ #if CONTROL_EXTRA_PRINTING
+ std::cout << "\tMy factor is at " << &member
+ << " and my base is at " << static_cast<base_class *>(this) << '.'
+ << std::endl;
+ #endif
+}
+
+// Destroy a good_class_1, noting the proper destruction order
+good_class_1::~good_class_1
+(
+)
+{
+ PRIVATE_REGISTER_DEATH( *this );
+
+ #if CONTROL_EXTRA_PRINTING
+ std::cout << "\tMy factor was at " << &member
+ << " and my base was at " << static_cast<base_class *>(this)
+ << '.' << std::endl;
+ #endif
+}
+
+// Create a good_class_2, noting the proper construction order
+good_class_2::good_class_2
+(
+)
+ : pbase_type0(), pbase_type1(-16, 0.125), pbase_type2(2, -3)
+ , base_type( pbase_type1::member, &this->pbase_type0::member,
+ &this->pbase_type2::member )
+{
+ PRIVATE_REGISTER_BIRTH( *this );
+
+ #if CONTROL_EXTRA_PRINTING
+ std::cout << "\tMy factors are at " << &this->pbase_type0::member
+ << ", " << &this->pbase_type1::member << ", "
+ << &this->pbase_type2::member << ", and my base is at "
+ << static_cast<base_class *>(this) << '.' << std::endl;
+ #endif
+}
+
+// Destroy a good_class_2, noting the proper destruction order
+good_class_2::~good_class_2
+(
+)
+{
+ PRIVATE_REGISTER_DEATH( *this );
+
+ #if CONTROL_EXTRA_PRINTING
+ std::cout << "\tMy factors were at " << &this->pbase_type0::member
+ << ", " << &this->pbase_type1::member << ", "
+ << &this->pbase_type2::member << ", and my base was at "
+ << static_cast<base_class *>(this) << '.' << std::endl;
+ #endif
+}
diff --git a/src/boost/libs/utility/test/binary_test.cpp b/src/boost/libs/utility/test/binary_test.cpp
new file mode 100644
index 000000000..f39dc08fb
--- /dev/null
+++ b/src/boost/libs/utility/test/binary_test.cpp
@@ -0,0 +1,647 @@
+/*=============================================================================
+ Copyright (c) 2006, 2007 Matthew Calabrese
+
+ Use, modification and distribution is subject to the Boost Software
+ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+ http://www.boost.org/LICENSE_1_0.txt)
+==============================================================================*/
+
+#include <boost/core/lightweight_test.hpp>
+#include <boost/utility/binary.hpp>
+#include <algorithm>
+#include <cstddef>
+
+#ifdef BOOST_MSVC
+#pragma warning(disable:4996) // warning C4996: 'std::equal': Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators'
+#endif
+
+/*
+Note: This file tests every single valid bit-grouping on its own, and some
+ random combinations of bit-groupings.
+*/
+
+std::size_t const num_random_test_values = 32;
+
+// Note: These hex values should all correspond with the binary array below
+unsigned int const random_unsigned_ints_hex[num_random_test_values]
+ = { 0x0103u, 0x77ebu, 0x5f36u, 0x1f18u, 0xc530u, 0xa73au, 0xd6f8u, 0x0919u
+ , 0xfbb0u, 0x3e7cu, 0xd0e9u, 0x22c8u, 0x724eu, 0x14fau, 0xd98eu, 0x40b5
+ , 0xeba0u, 0xfe50u, 0x688au, 0x1b05u, 0x5f9cu, 0xe4fcu, 0xa7b8u, 0xd3acu
+ , 0x1dddu, 0xbf04u, 0x8352u, 0xe89cu, 0x7506u, 0xe767u, 0xf489u, 0xe167
+ };
+
+unsigned int const random_unsigned_ints_binary[num_random_test_values]
+ = { BOOST_BINARY( 0 00010000 0011 ), BOOST_BINARY( 0 11101 1111 101011 )
+ , BOOST_BINARY( 010111 1100110 1 1 0 ), BOOST_BINARY( 000 1 11110 00 11000 )
+ , BOOST_BINARY( 110 001010 0110 000 ), BOOST_BINARY( 1010 01110011 1010 )
+ , BOOST_BINARY( 11 010 1 101111 1000 ), BOOST_BINARY( 0000 100100 0110 01 )
+ , BOOST_BINARY( 1111 101110 11 0000 ), BOOST_BINARY( 00111110 01111100 )
+ , BOOST_BINARY( 11 010 000111 01001 ), BOOST_BINARY( 00100 010110 01000 )
+ , BOOST_BINARY( 01 11001001 001110 ), BOOST_BINARY( 0010 1001111 1010 )
+ , BOOST_BINARY( 1101 1 00110 0 01110 ), BOOST_BINARY( 100 000 01011010 1 )
+ , BOOST_BINARY( 11 1010 1110 1000 00 ), BOOST_BINARY( 11111 110010 10000 )
+ , BOOST_BINARY( 01101 00010 001010 ), BOOST_BINARY( 000 11011 000001 01 )
+ , BOOST_BINARY( 01 01111 1100111 00 ), BOOST_BINARY( 1 110010 0111111 00 )
+ , BOOST_BINARY( 101 0011 11 01110 00 ), BOOST_BINARY( 110100 1 110101 100 )
+ , BOOST_BINARY( 00 1110111 011 101 ), BOOST_BINARY( 1011 1111 00000 100 )
+ , BOOST_BINARY( 1000 00110 101 0010 ), BOOST_BINARY( 1110 10001 001110 0 )
+ , BOOST_BINARY( 011 1010100 000 110 ), BOOST_BINARY( 1110 0111 01100 111 )
+ , BOOST_BINARY( 11110 10010 001001 ), BOOST_BINARY( 11 1000010 1100 111 )
+ };
+
+unsigned int const unsigned_ints_1_bit[2] =
+{ BOOST_BINARY( 0 )
+, BOOST_BINARY( 1 )
+};
+
+unsigned int const unsigned_ints_2_bits[4] =
+{ BOOST_BINARY( 00 )
+, BOOST_BINARY( 01 )
+, BOOST_BINARY( 10 )
+, BOOST_BINARY( 11 )
+};
+
+unsigned int const unsigned_ints_3_bits[8] =
+{ BOOST_BINARY( 000 )
+, BOOST_BINARY( 001 )
+, BOOST_BINARY( 010 )
+, BOOST_BINARY( 011 )
+, BOOST_BINARY( 100 )
+, BOOST_BINARY( 101 )
+, BOOST_BINARY( 110 )
+, BOOST_BINARY( 111 )
+};
+
+unsigned int const unsigned_ints_4_bits[16] =
+{ BOOST_BINARY( 0000 )
+, BOOST_BINARY( 0001 )
+, BOOST_BINARY( 0010 )
+, BOOST_BINARY( 0011 )
+, BOOST_BINARY( 0100 )
+, BOOST_BINARY( 0101 )
+, BOOST_BINARY( 0110 )
+, BOOST_BINARY( 0111 )
+, BOOST_BINARY( 1000 )
+, BOOST_BINARY( 1001 )
+, BOOST_BINARY( 1010 )
+, BOOST_BINARY( 1011 )
+, BOOST_BINARY( 1100 )
+, BOOST_BINARY( 1101 )
+, BOOST_BINARY( 1110 )
+, BOOST_BINARY( 1111 )
+};
+
+unsigned int const unsigned_ints_5_bits[32] =
+{ BOOST_BINARY( 00000 )
+, BOOST_BINARY( 00001 )
+, BOOST_BINARY( 00010 )
+, BOOST_BINARY( 00011 )
+, BOOST_BINARY( 00100 )
+, BOOST_BINARY( 00101 )
+, BOOST_BINARY( 00110 )
+, BOOST_BINARY( 00111 )
+, BOOST_BINARY( 01000 )
+, BOOST_BINARY( 01001 )
+, BOOST_BINARY( 01010 )
+, BOOST_BINARY( 01011 )
+, BOOST_BINARY( 01100 )
+, BOOST_BINARY( 01101 )
+, BOOST_BINARY( 01110 )
+, BOOST_BINARY( 01111 )
+, BOOST_BINARY( 10000 )
+, BOOST_BINARY( 10001 )
+, BOOST_BINARY( 10010 )
+, BOOST_BINARY( 10011 )
+, BOOST_BINARY( 10100 )
+, BOOST_BINARY( 10101 )
+, BOOST_BINARY( 10110 )
+, BOOST_BINARY( 10111 )
+, BOOST_BINARY( 11000 )
+, BOOST_BINARY( 11001 )
+, BOOST_BINARY( 11010 )
+, BOOST_BINARY( 11011 )
+, BOOST_BINARY( 11100 )
+, BOOST_BINARY( 11101 )
+, BOOST_BINARY( 11110 )
+, BOOST_BINARY( 11111 )
+};
+
+unsigned int const unsigned_ints_6_bits[64] =
+{ BOOST_BINARY( 000000 )
+, BOOST_BINARY( 000001 )
+, BOOST_BINARY( 000010 )
+, BOOST_BINARY( 000011 )
+, BOOST_BINARY( 000100 )
+, BOOST_BINARY( 000101 )
+, BOOST_BINARY( 000110 )
+, BOOST_BINARY( 000111 )
+, BOOST_BINARY( 001000 )
+, BOOST_BINARY( 001001 )
+, BOOST_BINARY( 001010 )
+, BOOST_BINARY( 001011 )
+, BOOST_BINARY( 001100 )
+, BOOST_BINARY( 001101 )
+, BOOST_BINARY( 001110 )
+, BOOST_BINARY( 001111 )
+, BOOST_BINARY( 010000 )
+, BOOST_BINARY( 010001 )
+, BOOST_BINARY( 010010 )
+, BOOST_BINARY( 010011 )
+, BOOST_BINARY( 010100 )
+, BOOST_BINARY( 010101 )
+, BOOST_BINARY( 010110 )
+, BOOST_BINARY( 010111 )
+, BOOST_BINARY( 011000 )
+, BOOST_BINARY( 011001 )
+, BOOST_BINARY( 011010 )
+, BOOST_BINARY( 011011 )
+, BOOST_BINARY( 011100 )
+, BOOST_BINARY( 011101 )
+, BOOST_BINARY( 011110 )
+, BOOST_BINARY( 011111 )
+, BOOST_BINARY( 100000 )
+, BOOST_BINARY( 100001 )
+, BOOST_BINARY( 100010 )
+, BOOST_BINARY( 100011 )
+, BOOST_BINARY( 100100 )
+, BOOST_BINARY( 100101 )
+, BOOST_BINARY( 100110 )
+, BOOST_BINARY( 100111 )
+, BOOST_BINARY( 101000 )
+, BOOST_BINARY( 101001 )
+, BOOST_BINARY( 101010 )
+, BOOST_BINARY( 101011 )
+, BOOST_BINARY( 101100 )
+, BOOST_BINARY( 101101 )
+, BOOST_BINARY( 101110 )
+, BOOST_BINARY( 101111 )
+, BOOST_BINARY( 110000 )
+, BOOST_BINARY( 110001 )
+, BOOST_BINARY( 110010 )
+, BOOST_BINARY( 110011 )
+, BOOST_BINARY( 110100 )
+, BOOST_BINARY( 110101 )
+, BOOST_BINARY( 110110 )
+, BOOST_BINARY( 110111 )
+, BOOST_BINARY( 111000 )
+, BOOST_BINARY( 111001 )
+, BOOST_BINARY( 111010 )
+, BOOST_BINARY( 111011 )
+, BOOST_BINARY( 111100 )
+, BOOST_BINARY( 111101 )
+, BOOST_BINARY( 111110 )
+, BOOST_BINARY( 111111 )
+};
+
+unsigned int const unsigned_ints_7_bits[128] =
+{ BOOST_BINARY( 0000000 )
+, BOOST_BINARY( 0000001 )
+, BOOST_BINARY( 0000010 )
+, BOOST_BINARY( 0000011 )
+, BOOST_BINARY( 0000100 )
+, BOOST_BINARY( 0000101 )
+, BOOST_BINARY( 0000110 )
+, BOOST_BINARY( 0000111 )
+, BOOST_BINARY( 0001000 )
+, BOOST_BINARY( 0001001 )
+, BOOST_BINARY( 0001010 )
+, BOOST_BINARY( 0001011 )
+, BOOST_BINARY( 0001100 )
+, BOOST_BINARY( 0001101 )
+, BOOST_BINARY( 0001110 )
+, BOOST_BINARY( 0001111 )
+, BOOST_BINARY( 0010000 )
+, BOOST_BINARY( 0010001 )
+, BOOST_BINARY( 0010010 )
+, BOOST_BINARY( 0010011 )
+, BOOST_BINARY( 0010100 )
+, BOOST_BINARY( 0010101 )
+, BOOST_BINARY( 0010110 )
+, BOOST_BINARY( 0010111 )
+, BOOST_BINARY( 0011000 )
+, BOOST_BINARY( 0011001 )
+, BOOST_BINARY( 0011010 )
+, BOOST_BINARY( 0011011 )
+, BOOST_BINARY( 0011100 )
+, BOOST_BINARY( 0011101 )
+, BOOST_BINARY( 0011110 )
+, BOOST_BINARY( 0011111 )
+, BOOST_BINARY( 0100000 )
+, BOOST_BINARY( 0100001 )
+, BOOST_BINARY( 0100010 )
+, BOOST_BINARY( 0100011 )
+, BOOST_BINARY( 0100100 )
+, BOOST_BINARY( 0100101 )
+, BOOST_BINARY( 0100110 )
+, BOOST_BINARY( 0100111 )
+, BOOST_BINARY( 0101000 )
+, BOOST_BINARY( 0101001 )
+, BOOST_BINARY( 0101010 )
+, BOOST_BINARY( 0101011 )
+, BOOST_BINARY( 0101100 )
+, BOOST_BINARY( 0101101 )
+, BOOST_BINARY( 0101110 )
+, BOOST_BINARY( 0101111 )
+, BOOST_BINARY( 0110000 )
+, BOOST_BINARY( 0110001 )
+, BOOST_BINARY( 0110010 )
+, BOOST_BINARY( 0110011 )
+, BOOST_BINARY( 0110100 )
+, BOOST_BINARY( 0110101 )
+, BOOST_BINARY( 0110110 )
+, BOOST_BINARY( 0110111 )
+, BOOST_BINARY( 0111000 )
+, BOOST_BINARY( 0111001 )
+, BOOST_BINARY( 0111010 )
+, BOOST_BINARY( 0111011 )
+, BOOST_BINARY( 0111100 )
+, BOOST_BINARY( 0111101 )
+, BOOST_BINARY( 0111110 )
+, BOOST_BINARY( 0111111 )
+, BOOST_BINARY( 1000000 )
+, BOOST_BINARY( 1000001 )
+, BOOST_BINARY( 1000010 )
+, BOOST_BINARY( 1000011 )
+, BOOST_BINARY( 1000100 )
+, BOOST_BINARY( 1000101 )
+, BOOST_BINARY( 1000110 )
+, BOOST_BINARY( 1000111 )
+, BOOST_BINARY( 1001000 )
+, BOOST_BINARY( 1001001 )
+, BOOST_BINARY( 1001010 )
+, BOOST_BINARY( 1001011 )
+, BOOST_BINARY( 1001100 )
+, BOOST_BINARY( 1001101 )
+, BOOST_BINARY( 1001110 )
+, BOOST_BINARY( 1001111 )
+, BOOST_BINARY( 1010000 )
+, BOOST_BINARY( 1010001 )
+, BOOST_BINARY( 1010010 )
+, BOOST_BINARY( 1010011 )
+, BOOST_BINARY( 1010100 )
+, BOOST_BINARY( 1010101 )
+, BOOST_BINARY( 1010110 )
+, BOOST_BINARY( 1010111 )
+, BOOST_BINARY( 1011000 )
+, BOOST_BINARY( 1011001 )
+, BOOST_BINARY( 1011010 )
+, BOOST_BINARY( 1011011 )
+, BOOST_BINARY( 1011100 )
+, BOOST_BINARY( 1011101 )
+, BOOST_BINARY( 1011110 )
+, BOOST_BINARY( 1011111 )
+, BOOST_BINARY( 1100000 )
+, BOOST_BINARY( 1100001 )
+, BOOST_BINARY( 1100010 )
+, BOOST_BINARY( 1100011 )
+, BOOST_BINARY( 1100100 )
+, BOOST_BINARY( 1100101 )
+, BOOST_BINARY( 1100110 )
+, BOOST_BINARY( 1100111 )
+, BOOST_BINARY( 1101000 )
+, BOOST_BINARY( 1101001 )
+, BOOST_BINARY( 1101010 )
+, BOOST_BINARY( 1101011 )
+, BOOST_BINARY( 1101100 )
+, BOOST_BINARY( 1101101 )
+, BOOST_BINARY( 1101110 )
+, BOOST_BINARY( 1101111 )
+, BOOST_BINARY( 1110000 )
+, BOOST_BINARY( 1110001 )
+, BOOST_BINARY( 1110010 )
+, BOOST_BINARY( 1110011 )
+, BOOST_BINARY( 1110100 )
+, BOOST_BINARY( 1110101 )
+, BOOST_BINARY( 1110110 )
+, BOOST_BINARY( 1110111 )
+, BOOST_BINARY( 1111000 )
+, BOOST_BINARY( 1111001 )
+, BOOST_BINARY( 1111010 )
+, BOOST_BINARY( 1111011 )
+, BOOST_BINARY( 1111100 )
+, BOOST_BINARY( 1111101 )
+, BOOST_BINARY( 1111110 )
+, BOOST_BINARY( 1111111 )
+};
+unsigned int const unsigned_ints_8_bits[256] =
+{ BOOST_BINARY( 00000000 )
+, BOOST_BINARY( 00000001 )
+, BOOST_BINARY( 00000010 )
+, BOOST_BINARY( 00000011 )
+, BOOST_BINARY( 00000100 )
+, BOOST_BINARY( 00000101 )
+, BOOST_BINARY( 00000110 )
+, BOOST_BINARY( 00000111 )
+, BOOST_BINARY( 00001000 )
+, BOOST_BINARY( 00001001 )
+, BOOST_BINARY( 00001010 )
+, BOOST_BINARY( 00001011 )
+, BOOST_BINARY( 00001100 )
+, BOOST_BINARY( 00001101 )
+, BOOST_BINARY( 00001110 )
+, BOOST_BINARY( 00001111 )
+, BOOST_BINARY( 00010000 )
+, BOOST_BINARY( 00010001 )
+, BOOST_BINARY( 00010010 )
+, BOOST_BINARY( 00010011 )
+, BOOST_BINARY( 00010100 )
+, BOOST_BINARY( 00010101 )
+, BOOST_BINARY( 00010110 )
+, BOOST_BINARY( 00010111 )
+, BOOST_BINARY( 00011000 )
+, BOOST_BINARY( 00011001 )
+, BOOST_BINARY( 00011010 )
+, BOOST_BINARY( 00011011 )
+, BOOST_BINARY( 00011100 )
+, BOOST_BINARY( 00011101 )
+, BOOST_BINARY( 00011110 )
+, BOOST_BINARY( 00011111 )
+, BOOST_BINARY( 00100000 )
+, BOOST_BINARY( 00100001 )
+, BOOST_BINARY( 00100010 )
+, BOOST_BINARY( 00100011 )
+, BOOST_BINARY( 00100100 )
+, BOOST_BINARY( 00100101 )
+, BOOST_BINARY( 00100110 )
+, BOOST_BINARY( 00100111 )
+, BOOST_BINARY( 00101000 )
+, BOOST_BINARY( 00101001 )
+, BOOST_BINARY( 00101010 )
+, BOOST_BINARY( 00101011 )
+, BOOST_BINARY( 00101100 )
+, BOOST_BINARY( 00101101 )
+, BOOST_BINARY( 00101110 )
+, BOOST_BINARY( 00101111 )
+, BOOST_BINARY( 00110000 )
+, BOOST_BINARY( 00110001 )
+, BOOST_BINARY( 00110010 )
+, BOOST_BINARY( 00110011 )
+, BOOST_BINARY( 00110100 )
+, BOOST_BINARY( 00110101 )
+, BOOST_BINARY( 00110110 )
+, BOOST_BINARY( 00110111 )
+, BOOST_BINARY( 00111000 )
+, BOOST_BINARY( 00111001 )
+, BOOST_BINARY( 00111010 )
+, BOOST_BINARY( 00111011 )
+, BOOST_BINARY( 00111100 )
+, BOOST_BINARY( 00111101 )
+, BOOST_BINARY( 00111110 )
+, BOOST_BINARY( 00111111 )
+, BOOST_BINARY( 01000000 )
+, BOOST_BINARY( 01000001 )
+, BOOST_BINARY( 01000010 )
+, BOOST_BINARY( 01000011 )
+, BOOST_BINARY( 01000100 )
+, BOOST_BINARY( 01000101 )
+, BOOST_BINARY( 01000110 )
+, BOOST_BINARY( 01000111 )
+, BOOST_BINARY( 01001000 )
+, BOOST_BINARY( 01001001 )
+, BOOST_BINARY( 01001010 )
+, BOOST_BINARY( 01001011 )
+, BOOST_BINARY( 01001100 )
+, BOOST_BINARY( 01001101 )
+, BOOST_BINARY( 01001110 )
+, BOOST_BINARY( 01001111 )
+, BOOST_BINARY( 01010000 )
+, BOOST_BINARY( 01010001 )
+, BOOST_BINARY( 01010010 )
+, BOOST_BINARY( 01010011 )
+, BOOST_BINARY( 01010100 )
+, BOOST_BINARY( 01010101 )
+, BOOST_BINARY( 01010110 )
+, BOOST_BINARY( 01010111 )
+, BOOST_BINARY( 01011000 )
+, BOOST_BINARY( 01011001 )
+, BOOST_BINARY( 01011010 )
+, BOOST_BINARY( 01011011 )
+, BOOST_BINARY( 01011100 )
+, BOOST_BINARY( 01011101 )
+, BOOST_BINARY( 01011110 )
+, BOOST_BINARY( 01011111 )
+, BOOST_BINARY( 01100000 )
+, BOOST_BINARY( 01100001 )
+, BOOST_BINARY( 01100010 )
+, BOOST_BINARY( 01100011 )
+, BOOST_BINARY( 01100100 )
+, BOOST_BINARY( 01100101 )
+, BOOST_BINARY( 01100110 )
+, BOOST_BINARY( 01100111 )
+, BOOST_BINARY( 01101000 )
+, BOOST_BINARY( 01101001 )
+, BOOST_BINARY( 01101010 )
+, BOOST_BINARY( 01101011 )
+, BOOST_BINARY( 01101100 )
+, BOOST_BINARY( 01101101 )
+, BOOST_BINARY( 01101110 )
+, BOOST_BINARY( 01101111 )
+, BOOST_BINARY( 01110000 )
+, BOOST_BINARY( 01110001 )
+, BOOST_BINARY( 01110010 )
+, BOOST_BINARY( 01110011 )
+, BOOST_BINARY( 01110100 )
+, BOOST_BINARY( 01110101 )
+, BOOST_BINARY( 01110110 )
+, BOOST_BINARY( 01110111 )
+, BOOST_BINARY( 01111000 )
+, BOOST_BINARY( 01111001 )
+, BOOST_BINARY( 01111010 )
+, BOOST_BINARY( 01111011 )
+, BOOST_BINARY( 01111100 )
+, BOOST_BINARY( 01111101 )
+, BOOST_BINARY( 01111110 )
+, BOOST_BINARY( 01111111 )
+, BOOST_BINARY( 10000000 )
+, BOOST_BINARY( 10000001 )
+, BOOST_BINARY( 10000010 )
+, BOOST_BINARY( 10000011 )
+, BOOST_BINARY( 10000100 )
+, BOOST_BINARY( 10000101 )
+, BOOST_BINARY( 10000110 )
+, BOOST_BINARY( 10000111 )
+, BOOST_BINARY( 10001000 )
+, BOOST_BINARY( 10001001 )
+, BOOST_BINARY( 10001010 )
+, BOOST_BINARY( 10001011 )
+, BOOST_BINARY( 10001100 )
+, BOOST_BINARY( 10001101 )
+, BOOST_BINARY( 10001110 )
+, BOOST_BINARY( 10001111 )
+, BOOST_BINARY( 10010000 )
+, BOOST_BINARY( 10010001 )
+, BOOST_BINARY( 10010010 )
+, BOOST_BINARY( 10010011 )
+, BOOST_BINARY( 10010100 )
+, BOOST_BINARY( 10010101 )
+, BOOST_BINARY( 10010110 )
+, BOOST_BINARY( 10010111 )
+, BOOST_BINARY( 10011000 )
+, BOOST_BINARY( 10011001 )
+, BOOST_BINARY( 10011010 )
+, BOOST_BINARY( 10011011 )
+, BOOST_BINARY( 10011100 )
+, BOOST_BINARY( 10011101 )
+, BOOST_BINARY( 10011110 )
+, BOOST_BINARY( 10011111 )
+, BOOST_BINARY( 10100000 )
+, BOOST_BINARY( 10100001 )
+, BOOST_BINARY( 10100010 )
+, BOOST_BINARY( 10100011 )
+, BOOST_BINARY( 10100100 )
+, BOOST_BINARY( 10100101 )
+, BOOST_BINARY( 10100110 )
+, BOOST_BINARY( 10100111 )
+, BOOST_BINARY( 10101000 )
+, BOOST_BINARY( 10101001 )
+, BOOST_BINARY( 10101010 )
+, BOOST_BINARY( 10101011 )
+, BOOST_BINARY( 10101100 )
+, BOOST_BINARY( 10101101 )
+, BOOST_BINARY( 10101110 )
+, BOOST_BINARY( 10101111 )
+, BOOST_BINARY( 10110000 )
+, BOOST_BINARY( 10110001 )
+, BOOST_BINARY( 10110010 )
+, BOOST_BINARY( 10110011 )
+, BOOST_BINARY( 10110100 )
+, BOOST_BINARY( 10110101 )
+, BOOST_BINARY( 10110110 )
+, BOOST_BINARY( 10110111 )
+, BOOST_BINARY( 10111000 )
+, BOOST_BINARY( 10111001 )
+, BOOST_BINARY( 10111010 )
+, BOOST_BINARY( 10111011 )
+, BOOST_BINARY( 10111100 )
+, BOOST_BINARY( 10111101 )
+, BOOST_BINARY( 10111110 )
+, BOOST_BINARY( 10111111 )
+, BOOST_BINARY( 11000000 )
+, BOOST_BINARY( 11000001 )
+, BOOST_BINARY( 11000010 )
+, BOOST_BINARY( 11000011 )
+, BOOST_BINARY( 11000100 )
+, BOOST_BINARY( 11000101 )
+, BOOST_BINARY( 11000110 )
+, BOOST_BINARY( 11000111 )
+, BOOST_BINARY( 11001000 )
+, BOOST_BINARY( 11001001 )
+, BOOST_BINARY( 11001010 )
+, BOOST_BINARY( 11001011 )
+, BOOST_BINARY( 11001100 )
+, BOOST_BINARY( 11001101 )
+, BOOST_BINARY( 11001110 )
+, BOOST_BINARY( 11001111 )
+, BOOST_BINARY( 11010000 )
+, BOOST_BINARY( 11010001 )
+, BOOST_BINARY( 11010010 )
+, BOOST_BINARY( 11010011 )
+, BOOST_BINARY( 11010100 )
+, BOOST_BINARY( 11010101 )
+, BOOST_BINARY( 11010110 )
+, BOOST_BINARY( 11010111 )
+, BOOST_BINARY( 11011000 )
+, BOOST_BINARY( 11011001 )
+, BOOST_BINARY( 11011010 )
+, BOOST_BINARY( 11011011 )
+, BOOST_BINARY( 11011100 )
+, BOOST_BINARY( 11011101 )
+, BOOST_BINARY( 11011110 )
+, BOOST_BINARY( 11011111 )
+, BOOST_BINARY( 11100000 )
+, BOOST_BINARY( 11100001 )
+, BOOST_BINARY( 11100010 )
+, BOOST_BINARY( 11100011 )
+, BOOST_BINARY( 11100100 )
+, BOOST_BINARY( 11100101 )
+, BOOST_BINARY( 11100110 )
+, BOOST_BINARY( 11100111 )
+, BOOST_BINARY( 11101000 )
+, BOOST_BINARY( 11101001 )
+, BOOST_BINARY( 11101010 )
+, BOOST_BINARY( 11101011 )
+, BOOST_BINARY( 11101100 )
+, BOOST_BINARY( 11101101 )
+, BOOST_BINARY( 11101110 )
+, BOOST_BINARY( 11101111 )
+, BOOST_BINARY( 11110000 )
+, BOOST_BINARY( 11110001 )
+, BOOST_BINARY( 11110010 )
+, BOOST_BINARY( 11110011 )
+, BOOST_BINARY( 11110100 )
+, BOOST_BINARY( 11110101 )
+, BOOST_BINARY( 11110110 )
+, BOOST_BINARY( 11110111 )
+, BOOST_BINARY( 11111000 )
+, BOOST_BINARY( 11111001 )
+, BOOST_BINARY( 11111010 )
+, BOOST_BINARY( 11111011 )
+, BOOST_BINARY( 11111100 )
+, BOOST_BINARY( 11111101 )
+, BOOST_BINARY( 11111110 )
+, BOOST_BINARY( 11111111 )
+};
+
+struct left_is_not_one_less_than_right
+{
+ bool operator ()( unsigned int left, unsigned int right ) const
+ {
+ return right != left + 1;
+ }
+};
+
+template< std::size_t Size >
+bool is_ascending_from_0_array( unsigned int const (&array)[Size] )
+{
+ unsigned int const* const curr = array,
+ * const end = array + Size;
+
+ return ( *curr == 0 )
+ && ( std::adjacent_find( curr, end
+ , left_is_not_one_less_than_right()
+ )
+ == end
+ );
+}
+
+std::size_t const unsigned_int_id = 1,
+ unsigned_long_int_id = 2;
+
+typedef char (&unsigned_int_id_type)[unsigned_int_id];
+typedef char (&unsigned_long_int_id_type)[unsigned_long_int_id];
+
+// Note: Functions only used for type checking
+unsigned_int_id_type binary_type_checker( unsigned int );
+unsigned_long_int_id_type binary_type_checker( unsigned long int );
+
+int main()
+{
+ BOOST_TEST( is_ascending_from_0_array( unsigned_ints_1_bit ) );
+ BOOST_TEST( is_ascending_from_0_array( unsigned_ints_2_bits ) );
+ BOOST_TEST( is_ascending_from_0_array( unsigned_ints_3_bits ) );
+ BOOST_TEST( is_ascending_from_0_array( unsigned_ints_4_bits ) );
+ BOOST_TEST( is_ascending_from_0_array( unsigned_ints_5_bits ) );
+ BOOST_TEST( is_ascending_from_0_array( unsigned_ints_6_bits ) );
+ BOOST_TEST( is_ascending_from_0_array( unsigned_ints_7_bits ) );
+ BOOST_TEST( is_ascending_from_0_array( unsigned_ints_8_bits ) );
+
+ BOOST_TEST( std::equal( &random_unsigned_ints_hex[0]
+ , random_unsigned_ints_hex + num_random_test_values
+ , &random_unsigned_ints_binary[0]
+ )
+ );
+
+ BOOST_TEST( sizeof( binary_type_checker( BOOST_BINARY_U( 110100 1010 ) ) )
+ == unsigned_int_id
+ );
+
+ BOOST_TEST( sizeof( binary_type_checker( BOOST_BINARY_UL( 11110 ) ) )
+ == unsigned_long_int_id
+ );
+
+ BOOST_TEST( sizeof( binary_type_checker( BOOST_BINARY_LU( 10 0001 ) ) )
+ == unsigned_long_int_id
+ );
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/utility/test/call_traits_test.cpp b/src/boost/libs/utility/test/call_traits_test.cpp
new file mode 100644
index 000000000..9e49b68a4
--- /dev/null
+++ b/src/boost/libs/utility/test/call_traits_test.cpp
@@ -0,0 +1,418 @@
+// boost::compressed_pair test program
+
+// (C) Copyright John Maddock 2000.
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt).
+
+
+// standalone test program for <boost/call_traits.hpp>
+// 18 Mar 2002:
+// Changed some names to prevent conflicts with some new type_traits additions.
+// 03 Oct 2000:
+// Enabled extra tests for VC6.
+
+#include <iostream>
+#include <iomanip>
+#include <algorithm>
+#include <typeinfo>
+#include <boost/call_traits.hpp>
+
+#include <libs/type_traits/test/test.hpp>
+#include <libs/type_traits/test/check_type.hpp>
+
+#ifdef BOOST_MSVC
+#pragma warning(disable:4181) // : warning C4181: qualifier applied to reference type; ignored
+#endif
+
+// a way prevent warnings for unused variables
+template<class T> inline void unused_variable(const T&) {}
+
+//
+// struct contained models a type that contains a type (for example std::pair)
+// arrays are contained by value, and have to be treated as a special case:
+//
+template <class T>
+struct contained
+{
+ // define our typedefs first, arrays are stored by value
+ // so value_type is not the same as result_type:
+ typedef typename boost::call_traits<T>::param_type param_type;
+ typedef typename boost::call_traits<T>::reference reference;
+ typedef typename boost::call_traits<T>::const_reference const_reference;
+ typedef T value_type;
+ typedef typename boost::call_traits<T>::value_type result_type;
+
+ // stored value:
+ value_type v_;
+
+ // constructors:
+ contained() {}
+ contained(param_type p) : v_(p){}
+ // return byval:
+ result_type value()const { return v_; }
+ // return by_ref:
+ reference get() { return v_; }
+ const_reference const_get()const { return v_; }
+ // pass value:
+ void call(param_type){}
+private:
+ contained& operator=(const contained&);
+};
+
+#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+template <class T, std::size_t N>
+struct contained<T[N]>
+{
+ typedef typename boost::call_traits<T[N]>::param_type param_type;
+ typedef typename boost::call_traits<T[N]>::reference reference;
+ typedef typename boost::call_traits<T[N]>::const_reference const_reference;
+ typedef T value_type[N];
+ typedef typename boost::call_traits<T[N]>::value_type result_type;
+
+ value_type v_;
+
+ contained(param_type p)
+ {
+ std::copy(p, p+N, v_);
+ }
+ // return byval:
+ result_type value()const { return v_; }
+ // return by_ref:
+ reference get() { return v_; }
+ const_reference const_get()const { return v_; }
+ void call(param_type){}
+private:
+ contained& operator=(const contained&);
+};
+#endif
+
+template <class T>
+contained<typename boost::call_traits<T>::value_type> test_wrap_type(const T& t)
+{
+ typedef typename boost::call_traits<T>::value_type ct;
+ return contained<ct>(t);
+}
+
+namespace test{
+
+template <class T1, class T2>
+std::pair<
+ typename boost::call_traits<T1>::value_type,
+ typename boost::call_traits<T2>::value_type>
+ make_pair(const T1& t1, const T2& t2)
+{
+ return std::pair<
+ typename boost::call_traits<T1>::value_type,
+ typename boost::call_traits<T2>::value_type>(t1, t2);
+}
+
+} // namespace test
+
+using namespace std;
+
+//
+// struct call_traits_checker:
+// verifies behaviour of contained example:
+//
+template <class T>
+struct call_traits_checker
+{
+ typedef typename boost::call_traits<T>::param_type param_type;
+ void operator()(param_type);
+};
+
+template <class T>
+void call_traits_checker<T>::operator()(param_type p)
+{
+ T t(p);
+ contained<T> c(t);
+ cout << "checking contained<" << typeid(T).name() << ">..." << endl;
+ BOOST_CHECK(t == c.value());
+ BOOST_CHECK(t == c.get());
+ BOOST_CHECK(t == c.const_get());
+#ifndef __ICL
+ //cout << "typeof contained<" << typeid(T).name() << ">::v_ is: " << typeid(&contained<T>::v_).name() << endl;
+ cout << "typeof contained<" << typeid(T).name() << ">::value() is: " << typeid(&contained<T>::value).name() << endl;
+ cout << "typeof contained<" << typeid(T).name() << ">::get() is: " << typeid(&contained<T>::get).name() << endl;
+ cout << "typeof contained<" << typeid(T).name() << ">::const_get() is: " << typeid(&contained<T>::const_get).name() << endl;
+ cout << "typeof contained<" << typeid(T).name() << ">::call() is: " << typeid(&contained<T>::call).name() << endl;
+ cout << endl;
+#endif
+}
+
+#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+template <class T, std::size_t N>
+struct call_traits_checker<T[N]>
+{
+ typedef typename boost::call_traits<T[N]>::param_type param_type;
+ void operator()(param_type t)
+ {
+ contained<T[N]> c(t);
+ cout << "checking contained<" << typeid(T[N]).name() << ">..." << endl;
+ unsigned int i = 0;
+ for(i = 0; i < N; ++i)
+ BOOST_CHECK(t[i] == c.value()[i]);
+ for(i = 0; i < N; ++i)
+ BOOST_CHECK(t[i] == c.get()[i]);
+ for(i = 0; i < N; ++i)
+ BOOST_CHECK(t[i] == c.const_get()[i]);
+
+ cout << "typeof contained<" << typeid(T[N]).name() << ">::v_ is: " << typeid(&contained<T[N]>::v_).name() << endl;
+ cout << "typeof contained<" << typeid(T[N]).name() << ">::value is: " << typeid(&contained<T[N]>::value).name() << endl;
+ cout << "typeof contained<" << typeid(T[N]).name() << ">::get is: " << typeid(&contained<T[N]>::get).name() << endl;
+ cout << "typeof contained<" << typeid(T[N]).name() << ">::const_get is: " << typeid(&contained<T[N]>::const_get).name() << endl;
+ cout << "typeof contained<" << typeid(T[N]).name() << ">::call is: " << typeid(&contained<T[N]>::call).name() << endl;
+ cout << endl;
+ }
+};
+#endif
+
+//
+// check_wrap:
+template <class W, class U>
+void check_wrap(const W& w, const U& u)
+{
+ cout << "checking " << typeid(W).name() << "..." << endl;
+ BOOST_CHECK(w.value() == u);
+}
+
+//
+// check_make_pair:
+// verifies behaviour of "make_pair":
+//
+template <class T, class U, class V>
+void check_make_pair(T c, U u, V v)
+{
+ cout << "checking std::pair<" << typeid(c.first).name() << ", " << typeid(c.second).name() << ">..." << endl;
+ BOOST_CHECK(c.first == u);
+ BOOST_CHECK(c.second == v);
+ cout << endl;
+}
+
+
+struct comparible_UDT
+{
+ int i_;
+ comparible_UDT() : i_(2){}
+ comparible_UDT(const comparible_UDT& other) : i_(other.i_){}
+ comparible_UDT& operator=(const comparible_UDT& other)
+ {
+ i_ = other.i_;
+ return *this;
+ }
+ bool operator == (const comparible_UDT& v){ return v.i_ == i_; }
+};
+
+int main()
+{
+ call_traits_checker<comparible_UDT> c1;
+ comparible_UDT u;
+ c1(u);
+ call_traits_checker<int> c2;
+ call_traits_checker<enum_UDT> c2b;
+ int i = 2;
+ c2(i);
+ c2b(one);
+ int* pi = &i;
+ int a[2] = {1,2};
+#if defined(BOOST_MSVC6_MEMBER_TEMPLATES) && !defined(__ICL)
+ call_traits_checker<int*> c3;
+ c3(pi);
+ call_traits_checker<int&> c4;
+ c4(i);
+ call_traits_checker<const int&> c5;
+ c5(i);
+#if !defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__MWERKS__) && !defined(__SUNPRO_CC)
+ call_traits_checker<int[2]> c6;
+ c6(a);
+#endif
+#endif
+
+ check_wrap(test_wrap_type(2), 2);
+#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__SUNPRO_CC)
+ check_wrap(test_wrap_type(a), a);
+ check_make_pair(test::make_pair(a, a), a, a);
+#endif
+
+ // cv-qualifiers applied to reference types should have no effect
+ // declare these here for later use with is_reference and remove_reference:
+ typedef int& r_type;
+ typedef const r_type cr_type;
+
+ BOOST_CHECK_TYPE(comparible_UDT, boost::call_traits<comparible_UDT>::value_type);
+ BOOST_CHECK_TYPE(comparible_UDT&, boost::call_traits<comparible_UDT>::reference);
+ BOOST_CHECK_TYPE(const comparible_UDT&, boost::call_traits<comparible_UDT>::const_reference);
+ BOOST_CHECK_TYPE(const comparible_UDT&, boost::call_traits<comparible_UDT>::param_type);
+ BOOST_CHECK_TYPE(int, boost::call_traits<int>::value_type);
+ BOOST_CHECK_TYPE(int&, boost::call_traits<int>::reference);
+ BOOST_CHECK_TYPE(const int&, boost::call_traits<int>::const_reference);
+ BOOST_CHECK_TYPE(const int, boost::call_traits<int>::param_type);
+ BOOST_CHECK_TYPE(int*, boost::call_traits<int*>::value_type);
+ BOOST_CHECK_TYPE(int*&, boost::call_traits<int*>::reference);
+ BOOST_CHECK_TYPE(int*const&, boost::call_traits<int*>::const_reference);
+ BOOST_CHECK_TYPE(int*const, boost::call_traits<int*>::param_type);
+#if defined(BOOST_MSVC6_MEMBER_TEMPLATES)
+ BOOST_CHECK_TYPE(int&, boost::call_traits<int&>::value_type);
+ BOOST_CHECK_TYPE(int&, boost::call_traits<int&>::reference);
+ BOOST_CHECK_TYPE(const int&, boost::call_traits<int&>::const_reference);
+ BOOST_CHECK_TYPE(int&, boost::call_traits<int&>::param_type);
+#if !(defined(__GNUC__) && ((__GNUC__ < 3) || (__GNUC__ == 3) && (__GNUC_MINOR__ < 1)))
+ BOOST_CHECK_TYPE(int&, boost::call_traits<cr_type>::value_type);
+ BOOST_CHECK_TYPE(int&, boost::call_traits<cr_type>::reference);
+ BOOST_CHECK_TYPE(const int&, boost::call_traits<cr_type>::const_reference);
+ BOOST_CHECK_TYPE(int&, boost::call_traits<cr_type>::param_type);
+#else
+ std::cout << "Your compiler cannot instantiate call_traits<int&const>, skipping four tests (4 errors)" << std::endl;
+#endif
+ BOOST_CHECK_TYPE(const int&, boost::call_traits<const int&>::value_type);
+ BOOST_CHECK_TYPE(const int&, boost::call_traits<const int&>::reference);
+ BOOST_CHECK_TYPE(const int&, boost::call_traits<const int&>::const_reference);
+ BOOST_CHECK_TYPE(const int&, boost::call_traits<const int&>::param_type);
+#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+ BOOST_CHECK_TYPE(const int*, boost::call_traits<int[3]>::value_type);
+ BOOST_CHECK_TYPE(int(&)[3], boost::call_traits<int[3]>::reference);
+ BOOST_CHECK_TYPE(const int(&)[3], boost::call_traits<int[3]>::const_reference);
+ BOOST_CHECK_TYPE(const int*const, boost::call_traits<int[3]>::param_type);
+ BOOST_CHECK_TYPE(const int*, boost::call_traits<const int[3]>::value_type);
+ BOOST_CHECK_TYPE(const int(&)[3], boost::call_traits<const int[3]>::reference);
+ BOOST_CHECK_TYPE(const int(&)[3], boost::call_traits<const int[3]>::const_reference);
+ BOOST_CHECK_TYPE(const int*const, boost::call_traits<const int[3]>::param_type);
+ // test with abstract base class:
+ BOOST_CHECK_TYPE(test_abc1, boost::call_traits<test_abc1>::value_type);
+ BOOST_CHECK_TYPE(test_abc1&, boost::call_traits<test_abc1>::reference);
+ BOOST_CHECK_TYPE(const test_abc1&, boost::call_traits<test_abc1>::const_reference);
+ BOOST_CHECK_TYPE(const test_abc1&, boost::call_traits<test_abc1>::param_type);
+#else
+ std::cout << "You're compiler does not support partial template specialiation, skipping 8 tests (8 errors)" << std::endl;
+#endif
+#else
+ std::cout << "You're compiler does not support partial template specialiation, skipping 20 tests (20 errors)" << std::endl;
+#endif
+ // test with an incomplete type:
+ BOOST_CHECK_TYPE(incomplete_type, boost::call_traits<incomplete_type>::value_type);
+ BOOST_CHECK_TYPE(incomplete_type&, boost::call_traits<incomplete_type>::reference);
+ BOOST_CHECK_TYPE(const incomplete_type&, boost::call_traits<incomplete_type>::const_reference);
+ BOOST_CHECK_TYPE(const incomplete_type&, boost::call_traits<incomplete_type>::param_type);
+ // test enum:
+ BOOST_CHECK_TYPE(enum_UDT, boost::call_traits<enum_UDT>::value_type);
+ BOOST_CHECK_TYPE(enum_UDT&, boost::call_traits<enum_UDT>::reference);
+ BOOST_CHECK_TYPE(const enum_UDT&, boost::call_traits<enum_UDT>::const_reference);
+ BOOST_CHECK_TYPE(const enum_UDT, boost::call_traits<enum_UDT>::param_type);
+ return 0;
+}
+
+//
+// define call_traits tests to check that the assertions in the docs do actually work
+// this is an compile-time only set of tests:
+//
+template <typename T, bool isarray = false>
+struct call_traits_test
+{
+ typedef ::boost::call_traits<T> ct;
+ typedef typename ct::param_type param_type;
+ typedef typename ct::reference reference;
+ typedef typename ct::const_reference const_reference;
+ typedef typename ct::value_type value_type;
+ static void assert_construct(param_type val);
+};
+
+template <typename T, bool isarray>
+void call_traits_test<T, isarray>::assert_construct(typename call_traits_test<T, isarray>::param_type val)
+{
+ //
+ // this is to check that the call_traits assertions are valid:
+ T t(val);
+ value_type v(t);
+ reference r(t);
+ const_reference cr(t);
+ param_type p(t);
+ value_type v2(v);
+ value_type v3(r);
+ value_type v4(p);
+ reference r2(v);
+ reference r3(r);
+ const_reference cr2(v);
+ const_reference cr3(r);
+ const_reference cr4(cr);
+ const_reference cr5(p);
+ param_type p2(v);
+ param_type p3(r);
+ param_type p4(p);
+
+ unused_variable(v2);
+ unused_variable(v3);
+ unused_variable(v4);
+ unused_variable(r2);
+ unused_variable(r3);
+ unused_variable(cr2);
+ unused_variable(cr3);
+ unused_variable(cr4);
+ unused_variable(cr5);
+ unused_variable(p2);
+ unused_variable(p3);
+ unused_variable(p4);
+}
+#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+template <typename T>
+struct call_traits_test<T, true>
+{
+ typedef ::boost::call_traits<T> ct;
+ typedef typename ct::param_type param_type;
+ typedef typename ct::reference reference;
+ typedef typename ct::const_reference const_reference;
+ typedef typename ct::value_type value_type;
+ static void assert_construct(param_type val);
+};
+
+template <typename T>
+void call_traits_test<T, true>::assert_construct(typename boost::call_traits<T>::param_type val)
+{
+ //
+ // this is to check that the call_traits assertions are valid:
+ T t;
+ value_type v(t);
+ value_type v5(val);
+ reference r = t;
+ const_reference cr = t;
+ reference r2 = r;
+ #ifndef __BORLANDC__
+ // C++ Builder buglet:
+ const_reference cr2 = r;
+ #endif
+ param_type p(t);
+ value_type v2(v);
+ const_reference cr3 = cr;
+ value_type v3(r);
+ value_type v4(p);
+ param_type p2(v);
+ param_type p3(r);
+ param_type p4(p);
+
+ unused_variable(v2);
+ unused_variable(v3);
+ unused_variable(v4);
+ unused_variable(v5);
+#ifndef __BORLANDC__
+ unused_variable(r2);
+ unused_variable(cr2);
+#endif
+ unused_variable(cr3);
+ unused_variable(p2);
+ unused_variable(p3);
+ unused_variable(p4);
+}
+#endif //BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+//
+// now check call_traits assertions by instantiating call_traits_test:
+template struct call_traits_test<int>;
+template struct call_traits_test<const int>;
+template struct call_traits_test<int*>;
+#if defined(BOOST_MSVC6_MEMBER_TEMPLATES)
+template struct call_traits_test<int&>;
+template struct call_traits_test<const int&>;
+#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__SUNPRO_CC)
+template struct call_traits_test<int[2], true>;
+#endif
+#endif
+
diff --git a/src/boost/libs/utility/test/compressed_pair_final_test.cpp b/src/boost/libs/utility/test/compressed_pair_final_test.cpp
new file mode 100644
index 000000000..247f3fceb
--- /dev/null
+++ b/src/boost/libs/utility/test/compressed_pair_final_test.cpp
@@ -0,0 +1,55 @@
+/*
+Copyright 2018 Glen Joseph Fernandes
+(glenjofe@gmail.com)
+
+Distributed under the Boost Software License, Version 1.0.
+(http://www.boost.org/LICENSE_1_0.txt)
+*/
+#include <boost/config.hpp>
+#if !defined(BOOST_NO_CXX11_FINAL)
+#include <boost/compressed_pair.hpp>
+#include <boost/core/lightweight_test.hpp>
+
+struct type1 {
+ operator bool() const {
+ return false;
+ }
+};
+
+struct type2 final {
+ operator bool() const {
+ return false;
+ }
+};
+
+#if !defined(BOOST_IS_FINAL)
+namespace boost {
+
+template<>
+struct is_final<type2>
+ : true_type { };
+
+} /* boost*/
+#endif
+
+template<class T1, class T2>
+void test()
+{
+ boost::compressed_pair<T1, T2> p;
+ BOOST_TEST(!p.first());
+ BOOST_TEST(!p.second());
+}
+
+int main()
+{
+ test<type1, type2>();
+ test<type2, type1>();
+ test<type2, type2>();
+ return boost::report_errors();
+}
+#else
+int main()
+{
+ return 0;
+}
+#endif
diff --git a/src/boost/libs/utility/test/compressed_pair_test.cpp b/src/boost/libs/utility/test/compressed_pair_test.cpp
new file mode 100644
index 000000000..ea10b2c0d
--- /dev/null
+++ b/src/boost/libs/utility/test/compressed_pair_test.cpp
@@ -0,0 +1,387 @@
+// boost::compressed_pair test program
+
+// (C) Copyright John Maddock 2000.
+// Use, modification and distribution are subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt).
+
+// standalone test program for <boost/compressed_pair.hpp>
+// Revised 03 Oct 2000:
+// Enabled tests for VC6.
+
+#include <iostream>
+#include <typeinfo>
+#include <cassert>
+
+#include <boost/compressed_pair.hpp>
+#include <boost/core/lightweight_test.hpp>
+
+using namespace boost;
+
+struct empty_UDT
+{
+ ~empty_UDT(){};
+ empty_UDT& operator=(const empty_UDT&){ return *this; }
+ bool operator==(const empty_UDT&)const
+ { return true; }
+};
+struct empty_POD_UDT
+{
+ empty_POD_UDT& operator=(const empty_POD_UDT&){ return *this; }
+ bool operator==(const empty_POD_UDT&)const
+ { return true; }
+};
+
+struct non_empty1
+{
+ int i;
+ non_empty1() : i(1){}
+ non_empty1(int v) : i(v){}
+ friend bool operator==(const non_empty1& a, const non_empty1& b)
+ { return a.i == b.i; }
+};
+
+struct non_empty2
+{
+ int i;
+ non_empty2() : i(3){}
+ non_empty2(int v) : i(v){}
+ friend bool operator==(const non_empty2& a, const non_empty2& b)
+ { return a.i == b.i; }
+};
+
+#ifdef __GNUC__
+using std::swap;
+#endif
+
+template <class T1, class T2>
+struct compressed_pair_tester
+{
+ // define the types we need:
+ typedef T1 first_type;
+ typedef T2 second_type;
+ typedef typename call_traits<first_type>::param_type first_param_type;
+ typedef typename call_traits<second_type>::param_type second_param_type;
+ // define our test proc:
+ static void test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4);
+};
+
+template <class T1, class T2>
+void compressed_pair_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4)
+{
+#ifndef __GNUC__
+ // gcc 2.90 can't cope with function scope using
+ // declarations, and generates an internal compiler error...
+ using std::swap;
+#endif
+ // default construct:
+ boost::compressed_pair<T1,T2> cp1;
+ // first param construct:
+ boost::compressed_pair<T1,T2> cp2(p1);
+ cp2.second() = p2;
+ BOOST_TEST(cp2.first() == p1);
+ BOOST_TEST(cp2.second() == p2);
+ // second param construct:
+ boost::compressed_pair<T1,T2> cp3(p2);
+ cp3.first() = p1;
+ BOOST_TEST(cp3.second() == p2);
+ BOOST_TEST(cp3.first() == p1);
+ // both param construct:
+ boost::compressed_pair<T1,T2> cp4(p1, p2);
+ BOOST_TEST(cp4.first() == p1);
+ BOOST_TEST(cp4.second() == p2);
+ boost::compressed_pair<T1,T2> cp5(p3, p4);
+ BOOST_TEST(cp5.first() == p3);
+ BOOST_TEST(cp5.second() == p4);
+ // check const members:
+ const boost::compressed_pair<T1,T2>& cpr1 = cp4;
+ BOOST_TEST(cpr1.first() == p1);
+ BOOST_TEST(cpr1.second() == p2);
+
+ // copy construct:
+ boost::compressed_pair<T1,T2> cp6(cp4);
+ BOOST_TEST(cp6.first() == p1);
+ BOOST_TEST(cp6.second() == p2);
+ // assignment:
+ cp1 = cp4;
+ BOOST_TEST(cp1.first() == p1);
+ BOOST_TEST(cp1.second() == p2);
+ cp1 = cp5;
+ BOOST_TEST(cp1.first() == p3);
+ BOOST_TEST(cp1.second() == p4);
+ // swap:
+ cp4.swap(cp5);
+ BOOST_TEST(cp4.first() == p3);
+ BOOST_TEST(cp4.second() == p4);
+ BOOST_TEST(cp5.first() == p1);
+ BOOST_TEST(cp5.second() == p2);
+ swap(cp4,cp5);
+ BOOST_TEST(cp4.first() == p1);
+ BOOST_TEST(cp4.second() == p2);
+ BOOST_TEST(cp5.first() == p3);
+ BOOST_TEST(cp5.second() == p4);
+}
+
+//
+// tests for case where one or both
+// parameters are reference types:
+//
+template <class T1, class T2>
+struct compressed_pair_reference_tester
+{
+ // define the types we need:
+ typedef T1 first_type;
+ typedef T2 second_type;
+ typedef typename call_traits<first_type>::param_type first_param_type;
+ typedef typename call_traits<second_type>::param_type second_param_type;
+ // define our test proc:
+ static void test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4);
+};
+
+template <class T1, class T2>
+void compressed_pair_reference_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4)
+{
+#ifndef __GNUC__
+ // gcc 2.90 can't cope with function scope using
+ // declarations, and generates an internal compiler error...
+ using std::swap;
+#endif
+ // both param construct:
+ boost::compressed_pair<T1,T2> cp4(p1, p2);
+ BOOST_TEST(cp4.first() == p1);
+ BOOST_TEST(cp4.second() == p2);
+ boost::compressed_pair<T1,T2> cp5(p3, p4);
+ BOOST_TEST(cp5.first() == p3);
+ BOOST_TEST(cp5.second() == p4);
+ // check const members:
+ const boost::compressed_pair<T1,T2>& cpr1 = cp4;
+ BOOST_TEST(cpr1.first() == p1);
+ BOOST_TEST(cpr1.second() == p2);
+
+ // copy construct:
+ boost::compressed_pair<T1,T2> cp6(cp4);
+ BOOST_TEST(cp6.first() == p1);
+ BOOST_TEST(cp6.second() == p2);
+ // assignment:
+ // VC6 bug:
+ // When second() is an empty class, VC6 performs the
+ // assignment by doing a memcpy - even though the empty
+ // class is really a zero sized base class, the result
+ // is that the memory of first() gets trampled over.
+ // Similar arguments apply to the case that first() is
+ // an empty base class.
+ // Strangely the problem is dependent upon the compiler
+ // settings - some generate the problem others do not.
+ cp4.first() = p3;
+ cp4.second() = p4;
+ BOOST_TEST(cp4.first() == p3);
+ BOOST_TEST(cp4.second() == p4);
+}
+//
+// supplimentary tests for case where first arg only is a reference type:
+//
+template <class T1, class T2>
+struct compressed_pair_reference1_tester
+{
+ // define the types we need:
+ typedef T1 first_type;
+ typedef T2 second_type;
+ typedef typename call_traits<first_type>::param_type first_param_type;
+ typedef typename call_traits<second_type>::param_type second_param_type;
+ // define our test proc:
+ static void test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4);
+};
+
+template <class T1, class T2>
+void compressed_pair_reference1_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type, second_param_type)
+{
+#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+ // first param construct:
+ boost::compressed_pair<T1,T2> cp2(p1);
+ cp2.second() = p2;
+ BOOST_TEST(cp2.first() == p1);
+ BOOST_TEST(cp2.second() == p2);
+#endif
+}
+//
+// supplimentary tests for case where second arg only is a reference type:
+//
+template <class T1, class T2>
+struct compressed_pair_reference2_tester
+{
+ // define the types we need:
+ typedef T1 first_type;
+ typedef T2 second_type;
+ typedef typename call_traits<first_type>::param_type first_param_type;
+ typedef typename call_traits<second_type>::param_type second_param_type;
+ // define our test proc:
+ static void test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4);
+};
+
+template <class T1, class T2>
+void compressed_pair_reference2_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type, second_param_type)
+{
+#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
+ // second param construct:
+ boost::compressed_pair<T1,T2> cp3(p2);
+ cp3.first() = p1;
+ BOOST_TEST(cp3.second() == p2);
+ BOOST_TEST(cp3.first() == p1);
+#endif
+}
+
+//
+// tests for where one or the other parameter is an array:
+//
+template <class T1, class T2>
+struct compressed_pair_array1_tester
+{
+ // define the types we need:
+ typedef T1 first_type;
+ typedef T2 second_type;
+ typedef typename call_traits<first_type>::param_type first_param_type;
+ typedef typename call_traits<second_type>::param_type second_param_type;
+ // define our test proc:
+ static void test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4);
+};
+
+template <class T1, class T2>
+void compressed_pair_array1_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type, second_param_type)
+{
+ // default construct:
+ boost::compressed_pair<T1,T2> cp1;
+ // second param construct:
+ boost::compressed_pair<T1,T2> cp3(p2);
+ cp3.first()[0] = p1[0];
+ BOOST_TEST(cp3.second() == p2);
+ BOOST_TEST(cp3.first()[0] == p1[0]);
+ // check const members:
+ const boost::compressed_pair<T1,T2>& cpr1 = cp3;
+ BOOST_TEST(cpr1.first()[0] == p1[0]);
+ BOOST_TEST(cpr1.second() == p2);
+
+ BOOST_TEST(sizeof(T1) == sizeof(cp1.first()));
+}
+
+template <class T1, class T2>
+struct compressed_pair_array2_tester
+{
+ // define the types we need:
+ typedef T1 first_type;
+ typedef T2 second_type;
+ typedef typename call_traits<first_type>::param_type first_param_type;
+ typedef typename call_traits<second_type>::param_type second_param_type;
+ // define our test proc:
+ static void test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4);
+};
+
+template <class T1, class T2>
+void compressed_pair_array2_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type, second_param_type)
+{
+ // default construct:
+ boost::compressed_pair<T1,T2> cp1;
+ // first param construct:
+ boost::compressed_pair<T1,T2> cp2(p1);
+ cp2.second()[0] = p2[0];
+ BOOST_TEST(cp2.first() == p1);
+ BOOST_TEST(cp2.second()[0] == p2[0]);
+ // check const members:
+ const boost::compressed_pair<T1,T2>& cpr1 = cp2;
+ BOOST_TEST(cpr1.first() == p1);
+ BOOST_TEST(cpr1.second()[0] == p2[0]);
+
+ BOOST_TEST(sizeof(T2) == sizeof(cp1.second()));
+}
+
+template <class T1, class T2>
+struct compressed_pair_array_tester
+{
+ // define the types we need:
+ typedef T1 first_type;
+ typedef T2 second_type;
+ typedef typename call_traits<first_type>::param_type first_param_type;
+ typedef typename call_traits<second_type>::param_type second_param_type;
+ // define our test proc:
+ static void test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4);
+};
+
+template <class T1, class T2>
+void compressed_pair_array_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type, second_param_type)
+{
+ // default construct:
+ boost::compressed_pair<T1,T2> cp1;
+ cp1.first()[0] = p1[0];
+ cp1.second()[0] = p2[0];
+ BOOST_TEST(cp1.first()[0] == p1[0]);
+ BOOST_TEST(cp1.second()[0] == p2[0]);
+ // check const members:
+ const boost::compressed_pair<T1,T2>& cpr1 = cp1;
+ BOOST_TEST(cpr1.first()[0] == p1[0]);
+ BOOST_TEST(cpr1.second()[0] == p2[0]);
+
+ BOOST_TEST(sizeof(T1) == sizeof(cp1.first()));
+ BOOST_TEST(sizeof(T2) == sizeof(cp1.second()));
+}
+
+int main()
+{
+ // declare some variables to pass to the tester:
+ non_empty1 ne1(2);
+ non_empty1 ne2(3);
+ non_empty2 ne3(4);
+ non_empty2 ne4(5);
+ empty_POD_UDT e1;
+ empty_UDT e2;
+
+ // T1 != T2, both non-empty
+ compressed_pair_tester<non_empty1,non_empty2>::test(ne1, ne3, ne2, ne4);
+ // T1 != T2, T2 empty
+ compressed_pair_tester<non_empty1,empty_POD_UDT>::test(ne1, e1, ne2, e1);
+ // T1 != T2, T1 empty
+ compressed_pair_tester<empty_POD_UDT,non_empty2>::test(e1, ne3, e1, ne4);
+ // T1 != T2, both empty
+ compressed_pair_tester<empty_POD_UDT,empty_UDT>::test(e1, e2, e1, e2);
+ // T1 == T2, both non-empty
+ compressed_pair_tester<non_empty1,non_empty1>::test(ne1, ne1, ne2, ne2);
+ // T1 == T2, both empty
+ compressed_pair_tester<empty_UDT,empty_UDT>::test(e2, e2, e2, e2);
+
+
+ // test references:
+
+ // T1 != T2, both non-empty
+ compressed_pair_reference_tester<non_empty1&,non_empty2>::test(ne1, ne3, ne2, ne4);
+ compressed_pair_reference_tester<non_empty1,non_empty2&>::test(ne1, ne3, ne2, ne4);
+ compressed_pair_reference1_tester<non_empty1&,non_empty2>::test(ne1, ne3, ne2, ne4);
+ compressed_pair_reference2_tester<non_empty1,non_empty2&>::test(ne1, ne3, ne2, ne4);
+ // T1 != T2, T2 empty
+ compressed_pair_reference_tester<non_empty1&,empty_POD_UDT>::test(ne1, e1, ne2, e1);
+ compressed_pair_reference1_tester<non_empty1&,empty_POD_UDT>::test(ne1, e1, ne2, e1);
+ // T1 != T2, T1 empty
+ compressed_pair_reference_tester<empty_POD_UDT,non_empty2&>::test(e1, ne3, e1, ne4);
+ compressed_pair_reference2_tester<empty_POD_UDT,non_empty2&>::test(e1, ne3, e1, ne4);
+ // T1 == T2, both non-empty
+ compressed_pair_reference_tester<non_empty1&,non_empty1&>::test(ne1, ne1, ne2, ne2);
+
+ // tests arrays:
+ non_empty1 nea1[2];
+ non_empty1 nea2[2];
+ non_empty2 nea3[2];
+ non_empty2 nea4[2];
+ nea1[0] = non_empty1(5);
+ nea2[0] = non_empty1(6);
+ nea3[0] = non_empty2(7);
+ nea4[0] = non_empty2(8);
+
+ // T1 != T2, both non-empty
+ compressed_pair_array1_tester<non_empty1[2],non_empty2>::test(nea1, ne3, nea2, ne4);
+ compressed_pair_array2_tester<non_empty1,non_empty2[2]>::test(ne1, nea3, ne2, nea4);
+ compressed_pair_array_tester<non_empty1[2],non_empty2[2]>::test(nea1, nea3, nea2, nea4);
+ // T1 != T2, T2 empty
+ compressed_pair_array1_tester<non_empty1[2],empty_POD_UDT>::test(nea1, e1, nea2, e1);
+ // T1 != T2, T1 empty
+ compressed_pair_array2_tester<empty_POD_UDT,non_empty2[2]>::test(e1, nea3, e1, nea4);
+ // T1 == T2, both non-empty
+ compressed_pair_array_tester<non_empty1[2],non_empty1[2]>::test(nea1, nea1, nea2, nea2);
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/utility/test/initialized_test.cpp b/src/boost/libs/utility/test/initialized_test.cpp
new file mode 100644
index 000000000..0b8852f12
--- /dev/null
+++ b/src/boost/libs/utility/test/initialized_test.cpp
@@ -0,0 +1,116 @@
+// Copyright 2010, Niels Dekker.
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// Test program for boost::initialized<T>.
+//
+// 2 May 2010 (Created) Niels Dekker
+
+#include <boost/utility/value_init.hpp>
+#include <boost/core/lightweight_test.hpp>
+
+#include <string>
+
+namespace
+{
+ // Typical use case for boost::initialized<T>: A generic class that
+ // holds a value of type T, which must be initialized by either
+ // value-initialization or direct-initialization.
+ template <class T> class key_value_pair
+ {
+ std::string m_key;
+ boost::initialized<T> m_value;
+ public:
+
+ // Value-initializes the object held by m_value.
+ key_value_pair() { }
+
+ // Value-initializes the object held by m_value.
+ explicit key_value_pair(const std::string& key)
+ :
+ m_key(key)
+ {
+ }
+
+ // Direct-initializes the object held by m_value.
+ key_value_pair(const std::string& key, const T& value)
+ :
+ m_key(key), m_value(value)
+ {
+ }
+
+ const T& get_value() const
+ {
+ return m_value;
+ }
+ };
+
+
+ // Tells whether the argument is value-initialized.
+ bool is_value_initialized(const int& arg)
+ {
+ return arg == 0;
+ }
+
+
+ // Tells whether the argument is value-initialized.
+ bool is_value_initialized(const std::string& arg)
+ {
+ return arg.empty();
+ }
+
+ struct foo
+ {
+ int data;
+ };
+
+ bool operator==(const foo& lhs, const foo& rhs)
+ {
+ return lhs.data == rhs.data;
+ }
+
+
+ // Tells whether the argument is value-initialized.
+ bool is_value_initialized(const foo& arg)
+ {
+ return arg.data == 0;
+ }
+
+
+ template <class T>
+ void test_key_value_pair(const T& magic_value)
+ {
+ // The value component of a default key_value_pair must be value-initialized.
+ key_value_pair<T> default_key_value_pair;
+ BOOST_TEST( is_value_initialized(default_key_value_pair.get_value() ) );
+
+ // The value component of a key_value_pair that only has its key explicitly specified
+ // must also be value-initialized.
+ BOOST_TEST( is_value_initialized(key_value_pair<T>("key").get_value()) );
+
+ // However, the value component of the following key_value_pair must be
+ // "magic_value", as it must be direct-initialized.
+ BOOST_TEST( key_value_pair<T>("key", magic_value).get_value() == magic_value );
+ }
+}
+
+
+// Tests boost::initialize for a fundamental type, a type with a
+// user-defined constructor, and a user-defined type without
+// a user-defined constructor.
+int main()
+{
+
+ const int magic_number = 42;
+ test_key_value_pair(magic_number);
+
+ const std::string magic_string = "magic value";
+ test_key_value_pair(magic_string);
+
+ const foo magic_foo = { 42 };
+ test_key_value_pair(magic_foo);
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/utility/test/initialized_test_fail1.cpp b/src/boost/libs/utility/test/initialized_test_fail1.cpp
new file mode 100644
index 000000000..ffeecab5b
--- /dev/null
+++ b/src/boost/libs/utility/test/initialized_test_fail1.cpp
@@ -0,0 +1,33 @@
+// Copyright 2010, Niels Dekker.
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// Test program for boost::initialized<T>. Must fail to compile.
+//
+// Initial: 2 May 2010
+
+#include <boost/utility/value_init.hpp>
+
+namespace
+{
+ void direct_initialize_from_int()
+ {
+ // Okay: initialized<T> supports direct-initialization from T.
+ boost::initialized<int> direct_initialized_int(1);
+ }
+
+ void copy_initialize_from_int()
+ {
+ // The following line should not compile, because initialized<T>
+ // was not intended to supports copy-initialization from T.
+ boost::initialized<int> copy_initialized_int = 1;
+ }
+}
+
+int main()
+{
+ // This should fail to compile, so there is no need to call any function.
+ return 0;
+}
diff --git a/src/boost/libs/utility/test/initialized_test_fail2.cpp b/src/boost/libs/utility/test/initialized_test_fail2.cpp
new file mode 100644
index 000000000..f3fbf391e
--- /dev/null
+++ b/src/boost/libs/utility/test/initialized_test_fail2.cpp
@@ -0,0 +1,37 @@
+// Copyright 2010, Niels Dekker.
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// Test program for boost::initialized<T>. Must fail to compile.
+//
+// Initial: 2 May 2010
+
+#include <boost/utility/value_init.hpp>
+
+namespace
+{
+ void from_value_initialized_to_initialized()
+ {
+ boost::value_initialized<int> value_initialized_int;
+
+ // Okay: initialized<T> can be initialized by value_initialized<T>.
+ boost::initialized<int> initialized_int(value_initialized_int);
+ }
+
+ void from_initialized_to_value_initialized()
+ {
+ boost::initialized<int> initialized_int(13);
+
+ // The following line should not compile, because initialized<T>
+ // should not be convertible to value_initialized<T>.
+ boost::value_initialized<int> value_initialized_int(initialized_int);
+ }
+}
+
+int main()
+{
+ // This should fail to compile, so there is no need to call any function.
+ return 0;
+}
diff --git a/src/boost/libs/utility/test/iterators_test.cpp b/src/boost/libs/utility/test/iterators_test.cpp
new file mode 100644
index 000000000..8f2d04d05
--- /dev/null
+++ b/src/boost/libs/utility/test/iterators_test.cpp
@@ -0,0 +1,322 @@
+// Demonstrate and test boost/operators.hpp on std::iterators --------------//
+
+// (C) Copyright Jeremy Siek 1999.
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org for most recent version including documentation.
+
+// Revision History
+// 29 May 01 Factored implementation, added comparison tests, use Test Tools
+// library (Daryle Walker)
+// 12 Dec 99 Initial version with iterator operators (Jeremy Siek)
+
+#include <boost/core/lightweight_test.hpp>
+
+#include <boost/config.hpp> // for BOOST_STATIC_CONSTANT
+#include <boost/operators.hpp> // for boost::random_access_iterator_helper
+
+#include <cstddef> // for std::ptrdiff_t, std::size_t
+#include <cstring> // for std::strcmp
+#include <iostream> // for std::cout (std::endl, ends, and flush indirectly)
+#include <string> // for std::string
+#include <sstream> // for std::stringstream
+
+# ifdef BOOST_NO_STDC_NAMESPACE
+ namespace std { using ::strcmp; }
+# endif
+
+
+// Iterator test class
+template <class T, class R, class P>
+struct test_iter
+ : public boost::random_access_iterator_helper<
+ test_iter<T,R,P>, T, std::ptrdiff_t, P, R>
+{
+ typedef test_iter self;
+ typedef R Reference;
+ typedef std::ptrdiff_t Distance;
+
+public:
+ explicit test_iter(T* i =0) : _i(i) { }
+ test_iter(const self& x) : _i(x._i) { }
+ self& operator=(const self& x) { _i = x._i; return *this; }
+ Reference operator*() const { return *_i; }
+ self& operator++() { ++_i; return *this; }
+ self& operator--() { --_i; return *this; }
+ self& operator+=(Distance n) { _i += n; return *this; }
+ self& operator-=(Distance n) { _i -= n; return *this; }
+ bool operator==(const self& x) const { return _i == x._i; }
+ bool operator<(const self& x) const { return _i < x._i; }
+ friend Distance operator-(const self& x, const self& y) {
+ return x._i - y._i;
+ }
+protected:
+ P _i;
+};
+
+// Iterator operator testing classes
+class test_opr_base
+{
+protected:
+ // Test data and types
+ BOOST_STATIC_CONSTANT( std::size_t, fruit_length = 6u );
+
+ typedef std::string fruit_array_type[ fruit_length ];
+
+ static fruit_array_type fruit;
+
+}; // test_opr_base
+
+#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
+// A definition is required even for integral static constants
+const std::size_t test_opr_base::fruit_length;
+#endif
+
+template <typename T, typename R = T&, typename P = T*>
+class test_opr
+ : public test_opr_base
+{
+ typedef test_opr<T, R, P> self_type;
+
+public:
+ // Types
+ typedef T value_type;
+ typedef R reference;
+ typedef P pointer;
+
+ typedef test_iter<T, R, P> iter_type;
+
+ // Test controller
+ static void master_test( char const name[] );
+
+private:
+ // Test data
+ static iter_type const fruit_begin;
+ static iter_type const fruit_end;
+
+ // Test parts
+ static void post_increment_test();
+ static void post_decrement_test();
+ static void indirect_referral_test();
+ static void offset_addition_test();
+ static void reverse_offset_addition_test();
+ static void offset_subtraction_test();
+ static void comparison_test();
+ static void indexing_test();
+
+}; // test_opr
+
+
+// Class-static data definitions
+test_opr_base::fruit_array_type
+ test_opr_base::fruit = { "apple", "orange", "pear", "peach", "grape", "plum" };
+
+template <typename T, typename R, typename P>
+ typename test_opr<T, R, P>::iter_type const
+ test_opr<T, R, P>::fruit_begin = test_iter<T,R,P>( fruit );
+
+template <typename T, typename R, typename P>
+typename test_opr<T, R, P>::iter_type const
+ test_opr<T, R, P>::fruit_end = test_iter<T,R,P>( fruit + fruit_length );
+
+
+// Main testing function
+int
+main()
+{
+ using std::string;
+
+ typedef test_opr<string, string &, string *> test1_type;
+ typedef test_opr<string, string const &, string const *> test2_type;
+
+ test1_type::master_test( "non-const string" );
+ test2_type::master_test( "const string" );
+
+ return boost::report_errors();
+}
+
+// Tests for all of the operators added by random_access_iterator_helper
+template <typename T, typename R, typename P>
+void
+test_opr<T, R, P>::master_test
+(
+ char const name[]
+)
+{
+ std::cout << "Doing test run for " << name << '.' << std::endl;
+
+ post_increment_test();
+ post_decrement_test();
+ indirect_referral_test();
+ offset_addition_test();
+ reverse_offset_addition_test();
+ offset_subtraction_test();
+ comparison_test();
+ indexing_test();
+}
+
+// Test post-increment
+template <typename T, typename R, typename P>
+void
+test_opr<T, R, P>::post_increment_test
+(
+)
+{
+ std::cout << "\tDoing post-increment test." << std::endl;
+
+ std::stringstream oss;
+ for ( iter_type i = fruit_begin ; i != fruit_end ; )
+ {
+ oss << *i++ << ' ';
+ }
+
+ BOOST_TEST( oss.str() == "apple orange pear peach grape plum ");
+}
+
+// Test post-decrement
+template <typename T, typename R, typename P>
+void
+test_opr<T, R, P>::post_decrement_test
+(
+)
+{
+ std::cout << "\tDoing post-decrement test." << std::endl;
+
+ std::stringstream oss;
+ for ( iter_type i = fruit_end ; i != fruit_begin ; )
+ {
+ i--;
+ oss << *i << ' ';
+ }
+
+ BOOST_TEST( oss.str() == "plum grape peach pear orange apple ");
+}
+
+// Test indirect structure referral
+template <typename T, typename R, typename P>
+void
+test_opr<T, R, P>::indirect_referral_test
+(
+)
+{
+ std::cout << "\tDoing indirect reference test." << std::endl;
+
+ std::stringstream oss;
+ for ( iter_type i = fruit_begin ; i != fruit_end ; ++i )
+ {
+ oss << i->size() << ' ';
+ }
+
+ BOOST_TEST( oss.str() == "5 6 4 5 5 4 ");
+}
+
+// Test offset addition
+template <typename T, typename R, typename P>
+void
+test_opr<T, R, P>::offset_addition_test
+(
+)
+{
+ std::cout << "\tDoing offset addition test." << std::endl;
+
+ std::ptrdiff_t const two = 2;
+ std::stringstream oss;
+ for ( iter_type i = fruit_begin ; i != fruit_end ; i = i + two )
+ {
+ oss << *i << ' ';
+ }
+
+ BOOST_TEST( oss.str() == "apple pear grape ");
+}
+
+// Test offset addition, in reverse order
+template <typename T, typename R, typename P>
+void
+test_opr<T, R, P>::reverse_offset_addition_test
+(
+)
+{
+ std::cout << "\tDoing reverse offset addition test." << std::endl;
+
+ std::ptrdiff_t const two = 2;
+ std::stringstream oss;
+ for ( iter_type i = fruit_begin ; i != fruit_end ; i = two + i )
+ {
+ oss << *i << ' ';
+ }
+
+ BOOST_TEST( oss.str() == "apple pear grape ");
+}
+
+// Test offset subtraction
+template <typename T, typename R, typename P>
+void
+test_opr<T, R, P>::offset_subtraction_test
+(
+)
+{
+ std::cout << "\tDoing offset subtraction test." << std::endl;
+
+ std::ptrdiff_t const two = 2;
+ std::stringstream oss;
+ for ( iter_type i = fruit_end ; fruit_begin < i ; )
+ {
+ i = i - two;
+ if ( (fruit_begin < i) || (fruit_begin == i) )
+ {
+ oss << *i << ' ';
+ }
+ }
+
+ BOOST_TEST( oss.str() == "grape pear apple ");
+}
+
+// Test comparisons
+template <typename T, typename R, typename P>
+void
+test_opr<T, R, P>::comparison_test
+(
+)
+{
+ using std::cout;
+ using std::ptrdiff_t;
+
+ cout << "\tDoing comparison tests.\n\t\tPass:";
+
+ for ( iter_type i = fruit_begin ; i != fruit_end ; ++i )
+ {
+ ptrdiff_t const i_offset = i - fruit_begin;
+
+ cout << ' ' << *i << std::flush;
+ for ( iter_type j = fruit_begin ; j != fruit_end ; ++j )
+ {
+ ptrdiff_t const j_offset = j - fruit_begin;
+
+ BOOST_TEST( (i != j) == (i_offset != j_offset) );
+ BOOST_TEST( (i > j) == (i_offset > j_offset) );
+ BOOST_TEST( (i <= j) == (i_offset <= j_offset) );
+ BOOST_TEST( (i >= j) == (i_offset >= j_offset) );
+ }
+ }
+ cout << std::endl;
+}
+
+// Test indexing
+template <typename T, typename R, typename P>
+void
+test_opr<T, R, P>::indexing_test
+(
+)
+{
+ std::cout << "\tDoing indexing test." << std::endl;
+
+ std::stringstream oss;
+ for ( std::size_t k = 0u ; k < fruit_length ; ++k )
+ {
+ oss << fruit_begin[ k ] << ' ';
+ }
+
+ BOOST_TEST( oss.str() == "apple orange pear peach grape plum ");
+}
diff --git a/src/boost/libs/utility/test/operators_test.cpp b/src/boost/libs/utility/test/operators_test.cpp
new file mode 100644
index 000000000..6cf7a76cf
--- /dev/null
+++ b/src/boost/libs/utility/test/operators_test.cpp
@@ -0,0 +1,936 @@
+// Demonstrate and test boost/operators.hpp -------------------------------//
+
+// Copyright Beman Dawes 1999. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+// See http://www.boost.org/libs/utility for documentation.
+
+// Revision History
+// 03 Apr 08 Added convertible_to_bool (Daniel Frey)
+// 01 Oct 01 Added tests for "left" operators
+// and new grouped operators. (Helmut Zeisel)
+// 20 May 01 Output progress messages. Added tests for new operator
+// templates. Updated random number generator. Changed tests to
+// use Boost Test Tools library. (Daryle Walker)
+// 04 Jun 00 Added regression test for a bug I found (David Abrahams)
+// 17 Jun 00 Fix for broken compilers (Aleksey Gurtovoy)
+// ?? ??? 00 Major update to randomly test all one- and two- argument forms by
+// wrapping integral types and comparing the results of operations
+// to the results for the raw types (David Abrahams)
+// 12 Dec 99 Minor update, output confirmation message.
+// 15 Nov 99 Initial version
+
+#include <boost/config.hpp> // for BOOST_MSVC
+#include <boost/operators.hpp> // for the tested items
+#include <boost/utility/detail/minstd_rand.hpp> // for boost::detail::minstd_rand
+#include <boost/core/lightweight_test.hpp>
+
+#include <iostream> // for std::cout (std::endl indirectly)
+
+
+namespace
+{
+ // avoiding a template version of true_value so as to not confuse VC++
+ int true_value(int x) { return x; }
+ long true_value(long x) { return x; }
+ signed char true_value(signed char x) { return x; }
+ unsigned int true_value(unsigned int x) { return x; }
+ unsigned long true_value(unsigned long x) { return x; }
+ unsigned char true_value(unsigned char x) { return x; }
+
+ // verify the minimum requirements for some operators
+ class convertible_to_bool
+ {
+ private:
+ bool _value;
+
+ typedef bool convertible_to_bool::*unspecified_bool_type;
+
+ void operator!() const;
+
+ public:
+ convertible_to_bool( const bool value ) : _value( value ) {}
+
+ operator unspecified_bool_type() const
+ { return _value ? &convertible_to_bool::_value : 0; }
+ };
+
+ // The use of operators<> here tended to obscure
+ // interactions with certain compiler bugs
+ template <class T>
+ class Wrapped1
+ : boost::operators<Wrapped1<T> >
+ , boost::shiftable<Wrapped1<T> >
+ {
+ public:
+ explicit Wrapped1( T v = T() ) : _value(v) {}
+ T value() const { return _value; }
+
+ convertible_to_bool operator<(const Wrapped1& x) const
+ { return _value < x._value; }
+ convertible_to_bool operator==(const Wrapped1& x) const
+ { return _value == x._value; }
+
+ Wrapped1& operator+=(const Wrapped1& x)
+ { _value += x._value; return *this; }
+ Wrapped1& operator-=(const Wrapped1& x)
+ { _value -= x._value; return *this; }
+ Wrapped1& operator*=(const Wrapped1& x)
+ { _value *= x._value; return *this; }
+ Wrapped1& operator/=(const Wrapped1& x)
+ { _value /= x._value; return *this; }
+ Wrapped1& operator%=(const Wrapped1& x)
+ { _value %= x._value; return *this; }
+ Wrapped1& operator|=(const Wrapped1& x)
+ { _value |= x._value; return *this; }
+ Wrapped1& operator&=(const Wrapped1& x)
+ { _value &= x._value; return *this; }
+ Wrapped1& operator^=(const Wrapped1& x)
+ { _value ^= x._value; return *this; }
+ Wrapped1& operator<<=(const Wrapped1& x)
+ { _value <<= x._value; return *this; }
+ Wrapped1& operator>>=(const Wrapped1& x)
+ { _value >>= x._value; return *this; }
+ Wrapped1& operator++() { ++_value; return *this; }
+ Wrapped1& operator--() { --_value; return *this; }
+
+ private:
+ T _value;
+ };
+ template <class T>
+ T true_value(Wrapped1<T> x) { return x.value(); }
+
+ template <class T, class U>
+ class Wrapped2
+ : boost::operators<Wrapped2<T, U> >
+ , boost::operators2<Wrapped2<T, U>, U>
+ , boost::shiftable1<Wrapped2<T, U>
+ , boost::shiftable2<Wrapped2<T, U>, U > >
+ {
+ public:
+ explicit Wrapped2( T v = T() ) : _value(v) {}
+ T value() const { return _value; }
+
+ convertible_to_bool operator<(const Wrapped2& x) const
+ { return _value < x._value; }
+ convertible_to_bool operator==(const Wrapped2& x) const
+ { return _value == x._value; }
+
+ Wrapped2& operator+=(const Wrapped2& x)
+ { _value += x._value; return *this; }
+ Wrapped2& operator-=(const Wrapped2& x)
+ { _value -= x._value; return *this; }
+ Wrapped2& operator*=(const Wrapped2& x)
+ { _value *= x._value; return *this; }
+ Wrapped2& operator/=(const Wrapped2& x)
+ { _value /= x._value; return *this; }
+ Wrapped2& operator%=(const Wrapped2& x)
+ { _value %= x._value; return *this; }
+ Wrapped2& operator|=(const Wrapped2& x)
+ { _value |= x._value; return *this; }
+ Wrapped2& operator&=(const Wrapped2& x)
+ { _value &= x._value; return *this; }
+ Wrapped2& operator^=(const Wrapped2& x)
+ { _value ^= x._value; return *this; }
+ Wrapped2& operator<<=(const Wrapped2& x)
+ { _value <<= x._value; return *this; }
+ Wrapped2& operator>>=(const Wrapped2& x)
+ { _value >>= x._value; return *this; }
+ Wrapped2& operator++() { ++_value; return *this; }
+ Wrapped2& operator--() { --_value; return *this; }
+
+ convertible_to_bool operator<(U u) const
+ { return _value < u; }
+ convertible_to_bool operator>(U u) const
+ { return _value > u; }
+ convertible_to_bool operator==(U u) const
+ { return _value == u; }
+
+ Wrapped2& operator+=(U u) { _value += u; return *this; }
+ Wrapped2& operator-=(U u) { _value -= u; return *this; }
+ Wrapped2& operator*=(U u) { _value *= u; return *this; }
+ Wrapped2& operator/=(U u) { _value /= u; return *this; }
+ Wrapped2& operator%=(U u) { _value %= u; return *this; }
+ Wrapped2& operator|=(U u) { _value |= u; return *this; }
+ Wrapped2& operator&=(U u) { _value &= u; return *this; }
+ Wrapped2& operator^=(U u) { _value ^= u; return *this; }
+ Wrapped2& operator<<=(U u) { _value <<= u; return *this; }
+ Wrapped2& operator>>=(U u) { _value >>= u; return *this; }
+
+ private:
+ T _value;
+ };
+ template <class T, class U>
+ T true_value(Wrapped2<T,U> x) { return x.value(); }
+
+ template <class T>
+ class Wrapped3
+ : boost::equivalent<Wrapped3<T> >
+ , boost::partially_ordered<Wrapped3<T> >
+ , boost::equality_comparable<Wrapped3<T> >
+ {
+ public:
+ explicit Wrapped3( T v = T() ) : _value(v) {}
+ T value() const { return _value; }
+
+ convertible_to_bool operator<(const Wrapped3& x) const
+ { return _value < x._value; }
+
+ private:
+ T _value;
+ };
+ template <class T>
+ T true_value(Wrapped3<T> x) { return x.value(); }
+
+ template <class T, class U>
+ class Wrapped4
+ : boost::equality_comparable1<Wrapped4<T, U>
+ , boost::equivalent1<Wrapped4<T, U>
+ , boost::partially_ordered1<Wrapped4<T, U> > > >
+ , boost::partially_ordered2<Wrapped4<T, U>, U
+ , boost::equivalent2<Wrapped4<T, U>, U
+ , boost::equality_comparable2<Wrapped4<T, U>, U> > >
+ {
+ public:
+ explicit Wrapped4( T v = T() ) : _value(v) {}
+ T value() const { return _value; }
+
+ convertible_to_bool operator<(const Wrapped4& x) const
+ { return _value < x._value; }
+
+ convertible_to_bool operator<(U u) const
+ { return _value < u; }
+ convertible_to_bool operator>(U u) const
+ { return _value > u; }
+
+ private:
+ T _value;
+ };
+ template <class T, class U>
+ T true_value(Wrapped4<T,U> x) { return x.value(); }
+
+ // U must be convertible to T
+ template <class T, class U>
+ class Wrapped5
+ : boost::ordered_field_operators2<Wrapped5<T, U>, U>
+ , boost::ordered_field_operators1<Wrapped5<T, U> >
+ {
+ public:
+ explicit Wrapped5( T v = T() ) : _value(v) {}
+
+ // Conversion from U to Wrapped5<T,U>
+ Wrapped5(U u) : _value(u) {}
+
+ T value() const { return _value; }
+
+ convertible_to_bool operator<(const Wrapped5& x) const
+ { return _value < x._value; }
+ convertible_to_bool operator<(U u) const
+ { return _value < u; }
+ convertible_to_bool operator>(U u) const
+ { return _value > u; }
+ convertible_to_bool operator==(const Wrapped5& u) const
+ { return _value == u._value; }
+ convertible_to_bool operator==(U u) const
+ { return _value == u; }
+
+ Wrapped5& operator/=(const Wrapped5& u) { _value /= u._value; return *this;}
+ Wrapped5& operator/=(U u) { _value /= u; return *this;}
+ Wrapped5& operator*=(const Wrapped5& u) { _value *= u._value; return *this;}
+ Wrapped5& operator*=(U u) { _value *= u; return *this;}
+ Wrapped5& operator-=(const Wrapped5& u) { _value -= u._value; return *this;}
+ Wrapped5& operator-=(U u) { _value -= u; return *this;}
+ Wrapped5& operator+=(const Wrapped5& u) { _value += u._value; return *this;}
+ Wrapped5& operator+=(U u) { _value += u; return *this;}
+
+ private:
+ T _value;
+ };
+ template <class T, class U>
+ T true_value(Wrapped5<T,U> x) { return x.value(); }
+
+ // U must be convertible to T
+ template <class T, class U>
+ class Wrapped6
+ : boost::ordered_euclidean_ring_operators2<Wrapped6<T, U>, U>
+ , boost::ordered_euclidean_ring_operators1<Wrapped6<T, U> >
+ {
+ public:
+ explicit Wrapped6( T v = T() ) : _value(v) {}
+
+ // Conversion from U to Wrapped6<T,U>
+ Wrapped6(U u) : _value(u) {}
+
+ T value() const { return _value; }
+
+ convertible_to_bool operator<(const Wrapped6& x) const
+ { return _value < x._value; }
+ convertible_to_bool operator<(U u) const
+ { return _value < u; }
+ convertible_to_bool operator>(U u) const
+ { return _value > u; }
+ convertible_to_bool operator==(const Wrapped6& u) const
+ { return _value == u._value; }
+ convertible_to_bool operator==(U u) const
+ { return _value == u; }
+
+ Wrapped6& operator%=(const Wrapped6& u) { _value %= u._value; return *this;}
+ Wrapped6& operator%=(U u) { _value %= u; return *this;}
+ Wrapped6& operator/=(const Wrapped6& u) { _value /= u._value; return *this;}
+ Wrapped6& operator/=(U u) { _value /= u; return *this;}
+ Wrapped6& operator*=(const Wrapped6& u) { _value *= u._value; return *this;}
+ Wrapped6& operator*=(U u) { _value *= u; return *this;}
+ Wrapped6& operator-=(const Wrapped6& u) { _value -= u._value; return *this;}
+ Wrapped6& operator-=(U u) { _value -= u; return *this;}
+ Wrapped6& operator+=(const Wrapped6& u) { _value += u._value; return *this;}
+ Wrapped6& operator+=(U u) { _value += u; return *this;}
+
+ private:
+ T _value;
+ };
+ template <class T, class U>
+ T true_value(Wrapped6<T,U> x) { return x.value(); }
+
+ // MyInt uses only the single template-argument form of all_operators<>
+ typedef Wrapped1<int> MyInt;
+
+ typedef Wrapped2<long, long> MyLong;
+
+ typedef Wrapped3<signed char> MyChar;
+
+ typedef Wrapped4<short, short> MyShort;
+
+ typedef Wrapped5<double, int> MyDoubleInt;
+
+ typedef Wrapped6<long, int> MyLongInt;
+
+ template <class X1, class Y1, class X2, class Y2>
+ void sanity_check(X1 x1, Y1 y1, X2 x2, Y2 y2)
+ {
+ BOOST_TEST( true_value(y1) == true_value(y2) );
+ BOOST_TEST( true_value(x1) == true_value(x2) );
+ }
+
+ template <class X1, class Y1, class X2, class Y2>
+ void test_less_than_comparable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
+ {
+ BOOST_TEST( static_cast<bool>(x1 < y1) == static_cast<bool>(x2 < y2) );
+ BOOST_TEST( static_cast<bool>(x1 <= y1) == static_cast<bool>(x2 <= y2) );
+ BOOST_TEST( static_cast<bool>(x1 >= y1) == static_cast<bool>(x2 >= y2) );
+ BOOST_TEST( static_cast<bool>(x1 > y1) == static_cast<bool>(x2 > y2) );
+ }
+
+ template <class X1, class Y1, class X2, class Y2>
+ void test_less_than_comparable(X1 x1, Y1 y1, X2 x2, Y2 y2)
+ {
+ sanity_check( x1, y1, x2, y2 );
+ test_less_than_comparable_aux( x1, y1, x2, y2 );
+ test_less_than_comparable_aux( y1, x1, y2, x2 );
+ }
+
+ template <class X1, class Y1, class X2, class Y2>
+ void test_equality_comparable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
+ {
+ BOOST_TEST( static_cast<bool>(x1 == y1) == static_cast<bool>(x2 == y2) );
+ BOOST_TEST( static_cast<bool>(x1 != y1) == static_cast<bool>(x2 != y2) );
+ }
+
+ template <class X1, class Y1, class X2, class Y2>
+ void test_equality_comparable(X1 x1, Y1 y1, X2 x2, Y2 y2)
+ {
+ sanity_check( x1, y1, x2, y2 );
+ test_equality_comparable_aux( x1, y1, x2, y2 );
+ test_equality_comparable_aux( y1, x1, y2, x2 );
+ }
+
+ template <class X1, class Y1, class X2, class Y2>
+ void test_multipliable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
+ {
+ BOOST_TEST( (x1 * y1).value() == (x2 * y2) );
+ }
+
+ template <class X1, class Y1, class X2, class Y2>
+ void test_multipliable(X1 x1, Y1 y1, X2 x2, Y2 y2)
+ {
+ sanity_check( x1, y1, x2, y2 );
+ test_multipliable_aux( x1, y1, x2, y2 );
+ test_multipliable_aux( y1, x1, y2, x2 );
+ }
+
+ template <class A, class B>
+ void test_value_equality(A a, B b)
+ {
+ BOOST_TEST(a.value() == b);
+ }
+
+#define TEST_OP_R(op) test_value_equality(x1 op y1, x2 op y2)
+#define TEST_OP_L(op) test_value_equality(y1 op x1, y2 op x2)
+
+ template <class X1, class Y1, class X2, class Y2>
+ void test_addable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
+ {
+ TEST_OP_R(+);
+ }
+
+ template <class X1, class Y1, class X2, class Y2>
+ void test_addable(X1 x1, Y1 y1, X2 x2, Y2 y2)
+ {
+ sanity_check( x1, y1, x2, y2 );
+ test_addable_aux( x1, y1, x2, y2 );
+ test_addable_aux( y1, x1, y2, x2 );
+ }
+
+ template <class X1, class Y1, class X2, class Y2>
+ void test_subtractable(X1 x1, Y1 y1, X2 x2, Y2 y2)
+ {
+ sanity_check( x1, y1, x2, y2 );
+ TEST_OP_R(-);
+ }
+
+ template <class X1, class Y1, class X2, class Y2>
+ void test_subtractable_left(X1 x1, Y1 y1, X2 x2, Y2 y2)
+ {
+ sanity_check( x1, y1, x2, y2 );
+ TEST_OP_L(-);
+ }
+
+ template <class X1, class Y1, class X2, class Y2>
+ void test_dividable(X1 x1, Y1 y1, X2 x2, Y2 y2)
+ {
+ sanity_check( x1, y1, x2, y2 );
+ if ( y2 != 0 )
+ TEST_OP_R(/);
+ }
+
+ template <class X1, class Y1, class X2, class Y2>
+ void test_dividable_left(X1 x1, Y1 y1, X2 x2, Y2 y2)
+ {
+ sanity_check( x1, y1, x2, y2 );
+ if ( x2 != 0 )
+ TEST_OP_L(/);
+ }
+
+ template <class X1, class Y1, class X2, class Y2>
+ void test_modable(X1 x1, Y1 y1, X2 x2, Y2 y2)
+ {
+ sanity_check( x1, y1, x2, y2 );
+ if ( y2 != 0 )
+ TEST_OP_R(%);
+ }
+
+ template <class X1, class Y1, class X2, class Y2>
+ void test_modable_left(X1 x1, Y1 y1, X2 x2, Y2 y2)
+ {
+ sanity_check( x1, y1, x2, y2 );
+ if ( x2 != 0 )
+ TEST_OP_L(%);
+ }
+
+ template <class X1, class Y1, class X2, class Y2>
+ void test_xorable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
+ {
+ TEST_OP_R(^);
+ }
+
+ template <class X1, class Y1, class X2, class Y2>
+ void test_xorable(X1 x1, Y1 y1, X2 x2, Y2 y2)
+ {
+ sanity_check( x1, y1, x2, y2 );
+ test_xorable_aux( x1, y1, x2, y2 );
+ test_xorable_aux( y1, x1, y2, x2 );
+ }
+
+ template <class X1, class Y1, class X2, class Y2>
+ void test_andable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
+ {
+ TEST_OP_R(&);
+ }
+
+ template <class X1, class Y1, class X2, class Y2>
+ void test_andable(X1 x1, Y1 y1, X2 x2, Y2 y2)
+ {
+ sanity_check( x1, y1, x2, y2 );
+ test_andable_aux( x1, y1, x2, y2 );
+ test_andable_aux( y1, x1, y2, x2 );
+ }
+
+ template <class X1, class Y1, class X2, class Y2>
+ void test_orable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
+ {
+ TEST_OP_R(|);
+ }
+
+ template <class X1, class Y1, class X2, class Y2>
+ void test_orable(X1 x1, Y1 y1, X2 x2, Y2 y2)
+ {
+ sanity_check( x1, y1, x2, y2 );
+ test_orable_aux( x1, y1, x2, y2 );
+ test_orable_aux( y1, x1, y2, x2 );
+ }
+
+ template <class X1, class Y1, class X2, class Y2>
+ void test_left_shiftable(X1 x1, Y1 y1, X2 x2, Y2 y2)
+ {
+ sanity_check( x1, y1, x2, y2 );
+ TEST_OP_R(<<);
+ }
+
+ template <class X1, class Y1, class X2, class Y2>
+ void test_right_shiftable(X1 x1, Y1 y1, X2 x2, Y2 y2)
+ {
+ sanity_check( x1, y1, x2, y2 );
+ TEST_OP_R(>>);
+ }
+
+ template <class X1, class X2>
+ void test_incrementable(X1 x1, X2 x2)
+ {
+ sanity_check( x1, x1, x2, x2 );
+ BOOST_TEST( (x1++).value() == x2++ );
+ BOOST_TEST( x1.value() == x2 );
+ }
+
+ template <class X1, class X2>
+ void test_decrementable(X1 x1, X2 x2)
+ {
+ sanity_check( x1, x1, x2, x2 );
+ BOOST_TEST( (x1--).value() == x2-- );
+ BOOST_TEST( x1.value() == x2 );
+ }
+
+ template <class X1, class Y1, class X2, class Y2>
+ void test_all(X1 x1, Y1 y1, X2 x2, Y2 y2)
+ {
+ test_less_than_comparable( x1, y1, x2, y2 );
+ test_equality_comparable( x1, y1, x2, y2 );
+ test_multipliable( x1, y1, x2, y2 );
+ test_addable( x1, y1, x2, y2 );
+ test_subtractable( x1, y1, x2, y2 );
+ test_dividable( x1, y1, x2, y2 );
+ test_modable( x1, y1, x2, y2 );
+ test_xorable( x1, y1, x2, y2 );
+ test_andable( x1, y1, x2, y2 );
+ test_orable( x1, y1, x2, y2 );
+ test_left_shiftable( x1, y1, x2, y2 );
+ test_right_shiftable( x1, y1, x2, y2 );
+ test_incrementable( x1, x2 );
+ test_decrementable( x1, x2 );
+ }
+
+ template <class X1, class Y1, class X2, class Y2>
+ void test_left(X1 x1, Y1 y1, X2 x2, Y2 y2)
+ {
+ test_subtractable_left( x1, y1, x2, y2 );
+ test_dividable_left( x1, y1, x2, y2 );
+ test_modable_left( x1, y1, x2, y2 );
+ }
+
+ template <class Big, class Small>
+ struct tester
+ {
+ void operator()(boost::detail::minstd_rand& randomizer) const
+ {
+ Big b1 = Big( randomizer() );
+ Big b2 = Big( randomizer() );
+ Small s = Small( randomizer() );
+
+ test_all( Wrapped1<Big>(b1), Wrapped1<Big>(b2), b1, b2 );
+ test_all( Wrapped2<Big, Small>(b1), s, b1, s );
+ }
+ };
+
+ template <class Big, class Small>
+ struct tester_left
+ {
+ void operator()(boost::detail::minstd_rand& randomizer) const
+ {
+ Big b1 = Big( randomizer() );
+ Small s = Small( randomizer() );
+
+ test_left( Wrapped6<Big, Small>(b1), s, b1, s );
+ }
+ };
+
+ // added as a regression test. We had a bug which this uncovered.
+ struct Point
+ : boost::addable<Point
+ , boost::subtractable<Point> >
+ {
+ Point( int h, int v ) : h(h), v(v) {}
+ Point() :h(0), v(0) {}
+ const Point& operator+=( const Point& rhs )
+ { h += rhs.h; v += rhs.v; return *this; }
+ const Point& operator-=( const Point& rhs )
+ { h -= rhs.h; v -= rhs.v; return *this; }
+
+ int h;
+ int v;
+ };
+
+} // unnamed namespace
+
+
+// workaround for MSVC bug; for some reasons the compiler doesn't instantiate
+// inherited operator templates at the moment it must, so the following
+// explicit instantiations force it to do that.
+
+#if defined(BOOST_MSVC) && (_MSC_VER < 1300)
+template Wrapped1<int>;
+template Wrapped1<long>;
+template Wrapped1<unsigned int>;
+template Wrapped1<unsigned long>;
+
+template Wrapped2<int, int>;
+template Wrapped2<int, signed char>;
+template Wrapped2<long, signed char>;
+template Wrapped2<long, int>;
+template Wrapped2<long, long>;
+template Wrapped2<unsigned int, unsigned int>;
+template Wrapped2<unsigned int, unsigned char>;
+template Wrapped2<unsigned long, unsigned int>;
+template Wrapped2<unsigned long, unsigned char>;
+template Wrapped2<unsigned long, unsigned long>;
+
+template Wrapped6<long, int>;
+template Wrapped6<long, signed char>;
+template Wrapped6<int, signed char>;
+template Wrapped6<unsigned long, unsigned int>;
+template Wrapped6<unsigned long, unsigned char>;
+template Wrapped6<unsigned int, unsigned char>;
+#endif
+
+#define PRIVATE_EXPR_TEST(e, t) BOOST_TEST( ((e), (t)) )
+
+int
+main()
+{
+ using std::cout;
+ using std::endl;
+
+ // Regression test.
+ Point x;
+ x = x + Point(3, 4);
+ x = x - Point(3, 4);
+
+ cout << "Created point, and operated on it." << endl;
+
+ for (int n = 0; n < 1000; ++n) // was 10,000 but took too long (Beman)
+ {
+ boost::detail::minstd_rand r;
+ tester<long, int>()(r);
+ tester<long, signed char>()(r);
+ tester<long, long>()(r);
+ tester<int, int>()(r);
+ tester<int, signed char>()(r);
+
+ tester<unsigned long, unsigned int>()(r);
+ tester<unsigned long, unsigned char>()(r);
+ tester<unsigned long, unsigned long>()(r);
+ tester<unsigned int, unsigned int>()(r);
+ tester<unsigned int, unsigned char>()(r);
+
+ tester_left<long, int>()(r);
+ tester_left<long, signed char>()(r);
+ tester_left<int, signed char>()(r);
+
+ tester_left<unsigned long, unsigned int>()(r);
+ tester_left<unsigned long, unsigned char>()(r);
+ tester_left<unsigned int, unsigned char>()(r);
+ }
+
+ cout << "Did random tester loop." << endl;
+
+ MyInt i1(1);
+ MyInt i2(2);
+ MyInt i;
+
+ BOOST_TEST( i1.value() == 1 );
+ BOOST_TEST( i2.value() == 2 );
+ BOOST_TEST( i.value() == 0 );
+
+ cout << "Created MyInt objects.\n";
+
+ PRIVATE_EXPR_TEST( (i = i2), (i.value() == 2) );
+
+ BOOST_TEST( static_cast<bool>(i2 == i) );
+ BOOST_TEST( static_cast<bool>(i1 != i2) );
+ BOOST_TEST( static_cast<bool>(i1 < i2) );
+ BOOST_TEST( static_cast<bool>(i1 <= i2) );
+ BOOST_TEST( static_cast<bool>(i <= i2) );
+ BOOST_TEST( static_cast<bool>(i2 > i1) );
+ BOOST_TEST( static_cast<bool>(i2 >= i1) );
+ BOOST_TEST( static_cast<bool>(i2 >= i) );
+
+ PRIVATE_EXPR_TEST( (i = i1 + i2), (i.value() == 3) );
+ PRIVATE_EXPR_TEST( (i = i + i2), (i.value() == 5) );
+ PRIVATE_EXPR_TEST( (i = i - i1), (i.value() == 4) );
+ PRIVATE_EXPR_TEST( (i = i * i2), (i.value() == 8) );
+ PRIVATE_EXPR_TEST( (i = i / i2), (i.value() == 4) );
+ PRIVATE_EXPR_TEST( (i = i % ( i - i1 )), (i.value() == 1) );
+ PRIVATE_EXPR_TEST( (i = i2 + i2), (i.value() == 4) );
+ PRIVATE_EXPR_TEST( (i = i1 | i2 | i), (i.value() == 7) );
+ PRIVATE_EXPR_TEST( (i = i & i2), (i.value() == 2) );
+ PRIVATE_EXPR_TEST( (i = i + i1), (i.value() == 3) );
+ PRIVATE_EXPR_TEST( (i = i ^ i1), (i.value() == 2) );
+ PRIVATE_EXPR_TEST( (i = ( i + i1 ) * ( i2 | i1 )), (i.value() == 9) );
+
+ PRIVATE_EXPR_TEST( (i = i1 << i2), (i.value() == 4) );
+ PRIVATE_EXPR_TEST( (i = i2 >> i1), (i.value() == 1) );
+
+ cout << "Performed tests on MyInt objects.\n";
+
+ MyLong j1(1);
+ MyLong j2(2);
+ MyLong j;
+
+ BOOST_TEST( j1.value() == 1 );
+ BOOST_TEST( j2.value() == 2 );
+ BOOST_TEST( j.value() == 0 );
+
+ cout << "Created MyLong objects.\n";
+
+ PRIVATE_EXPR_TEST( (j = j2), (j.value() == 2) );
+
+ BOOST_TEST( static_cast<bool>(j2 == j) );
+ BOOST_TEST( static_cast<bool>(2 == j) );
+ BOOST_TEST( static_cast<bool>(j2 == 2) );
+ BOOST_TEST( static_cast<bool>(j == j2) );
+ BOOST_TEST( static_cast<bool>(j1 != j2) );
+ BOOST_TEST( static_cast<bool>(j1 != 2) );
+ BOOST_TEST( static_cast<bool>(1 != j2) );
+ BOOST_TEST( static_cast<bool>(j1 < j2) );
+ BOOST_TEST( static_cast<bool>(1 < j2) );
+ BOOST_TEST( static_cast<bool>(j1 < 2) );
+ BOOST_TEST( static_cast<bool>(j1 <= j2) );
+ BOOST_TEST( static_cast<bool>(1 <= j2) );
+ BOOST_TEST( static_cast<bool>(j1 <= j) );
+ BOOST_TEST( static_cast<bool>(j <= j2) );
+ BOOST_TEST( static_cast<bool>(2 <= j2) );
+ BOOST_TEST( static_cast<bool>(j <= 2) );
+ BOOST_TEST( static_cast<bool>(j2 > j1) );
+ BOOST_TEST( static_cast<bool>(2 > j1) );
+ BOOST_TEST( static_cast<bool>(j2 > 1) );
+ BOOST_TEST( static_cast<bool>(j2 >= j1) );
+ BOOST_TEST( static_cast<bool>(2 >= j1) );
+ BOOST_TEST( static_cast<bool>(j2 >= 1) );
+ BOOST_TEST( static_cast<bool>(j2 >= j) );
+ BOOST_TEST( static_cast<bool>(2 >= j) );
+ BOOST_TEST( static_cast<bool>(j2 >= 2) );
+
+ BOOST_TEST( static_cast<bool>((j1 + 2) == 3) );
+ BOOST_TEST( static_cast<bool>((1 + j2) == 3) );
+ PRIVATE_EXPR_TEST( (j = j1 + j2), (j.value() == 3) );
+
+ BOOST_TEST( static_cast<bool>((j + 2) == 5) );
+ BOOST_TEST( static_cast<bool>((3 + j2) == 5) );
+ PRIVATE_EXPR_TEST( (j = j + j2), (j.value() == 5) );
+
+ BOOST_TEST( static_cast<bool>((j - 1) == 4) );
+ PRIVATE_EXPR_TEST( (j = j - j1), (j.value() == 4) );
+
+ BOOST_TEST( static_cast<bool>((j * 2) == 8) );
+ BOOST_TEST( static_cast<bool>((4 * j2) == 8) );
+ PRIVATE_EXPR_TEST( (j = j * j2), (j.value() == 8) );
+
+ BOOST_TEST( static_cast<bool>((j / 2) == 4) );
+ PRIVATE_EXPR_TEST( (j = j / j2), (j.value() == 4) );
+
+ BOOST_TEST( static_cast<bool>((j % 3) == 1) );
+ PRIVATE_EXPR_TEST( (j = j % ( j - j1 )), (j.value() == 1) );
+
+ PRIVATE_EXPR_TEST( (j = j2 + j2), (j.value() == 4) );
+
+ BOOST_TEST( static_cast<bool>((1 | j2 | j) == 7) );
+ BOOST_TEST( static_cast<bool>((j1 | 2 | j) == 7) );
+ BOOST_TEST( static_cast<bool>((j1 | j2 | 4) == 7) );
+ PRIVATE_EXPR_TEST( (j = j1 | j2 | j), (j.value() == 7) );
+
+ BOOST_TEST( static_cast<bool>((7 & j2) == 2) );
+ BOOST_TEST( static_cast<bool>((j & 2) == 2) );
+ PRIVATE_EXPR_TEST( (j = j & j2), (j.value() == 2) );
+
+ PRIVATE_EXPR_TEST( (j = j | j1), (j.value() == 3) );
+
+ BOOST_TEST( static_cast<bool>((3 ^ j1) == 2) );
+ BOOST_TEST( static_cast<bool>((j ^ 1) == 2) );
+ PRIVATE_EXPR_TEST( (j = j ^ j1), (j.value() == 2) );
+
+ PRIVATE_EXPR_TEST( (j = ( j + j1 ) * ( j2 | j1 )), (j.value() == 9) );
+
+ BOOST_TEST( static_cast<bool>((j1 << 2) == 4) );
+ BOOST_TEST( static_cast<bool>((j2 << 1) == 4) );
+ PRIVATE_EXPR_TEST( (j = j1 << j2), (j.value() == 4) );
+
+ BOOST_TEST( static_cast<bool>((j >> 2) == 1) );
+ BOOST_TEST( static_cast<bool>((j2 >> 1) == 1) );
+ PRIVATE_EXPR_TEST( (j = j2 >> j1), (j.value() == 1) );
+
+ cout << "Performed tests on MyLong objects.\n";
+
+ MyChar k1(1);
+ MyChar k2(2);
+ MyChar k;
+
+ BOOST_TEST( k1.value() == 1 );
+ BOOST_TEST( k2.value() == 2 );
+ BOOST_TEST( k.value() == 0 );
+
+ cout << "Created MyChar objects.\n";
+
+ PRIVATE_EXPR_TEST( (k = k2), (k.value() == 2) );
+
+ BOOST_TEST( static_cast<bool>(k2 == k) );
+ BOOST_TEST( static_cast<bool>(k1 != k2) );
+ BOOST_TEST( static_cast<bool>(k1 < k2) );
+ BOOST_TEST( static_cast<bool>(k1 <= k2) );
+ BOOST_TEST( static_cast<bool>(k <= k2) );
+ BOOST_TEST( static_cast<bool>(k2 > k1) );
+ BOOST_TEST( static_cast<bool>(k2 >= k1) );
+ BOOST_TEST( static_cast<bool>(k2 >= k) );
+
+ cout << "Performed tests on MyChar objects.\n";
+
+ MyShort l1(1);
+ MyShort l2(2);
+ MyShort l;
+
+ BOOST_TEST( l1.value() == 1 );
+ BOOST_TEST( l2.value() == 2 );
+ BOOST_TEST( l.value() == 0 );
+
+ cout << "Created MyShort objects.\n";
+
+ PRIVATE_EXPR_TEST( (l = l2), (l.value() == 2) );
+
+ BOOST_TEST( static_cast<bool>(l2 == l) );
+ BOOST_TEST( static_cast<bool>(2 == l) );
+ BOOST_TEST( static_cast<bool>(l2 == 2) );
+ BOOST_TEST( static_cast<bool>(l == l2) );
+ BOOST_TEST( static_cast<bool>(l1 != l2) );
+ BOOST_TEST( static_cast<bool>(l1 != 2) );
+ BOOST_TEST( static_cast<bool>(1 != l2) );
+ BOOST_TEST( static_cast<bool>(l1 < l2) );
+ BOOST_TEST( static_cast<bool>(1 < l2) );
+ BOOST_TEST( static_cast<bool>(l1 < 2) );
+ BOOST_TEST( static_cast<bool>(l1 <= l2) );
+ BOOST_TEST( static_cast<bool>(1 <= l2) );
+ BOOST_TEST( static_cast<bool>(l1 <= l) );
+ BOOST_TEST( static_cast<bool>(l <= l2) );
+ BOOST_TEST( static_cast<bool>(2 <= l2) );
+ BOOST_TEST( static_cast<bool>(l <= 2) );
+ BOOST_TEST( static_cast<bool>(l2 > l1) );
+ BOOST_TEST( static_cast<bool>(2 > l1) );
+ BOOST_TEST( static_cast<bool>(l2 > 1) );
+ BOOST_TEST( static_cast<bool>(l2 >= l1) );
+ BOOST_TEST( static_cast<bool>(2 >= l1) );
+ BOOST_TEST( static_cast<bool>(l2 >= 1) );
+ BOOST_TEST( static_cast<bool>(l2 >= l) );
+ BOOST_TEST( static_cast<bool>(2 >= l) );
+ BOOST_TEST( static_cast<bool>(l2 >= 2) );
+
+ cout << "Performed tests on MyShort objects.\n";
+
+ MyDoubleInt di1(1);
+ MyDoubleInt di2(2.);
+ MyDoubleInt half(0.5);
+ MyDoubleInt di;
+ MyDoubleInt tmp;
+
+ BOOST_TEST( di1.value() == 1 );
+ BOOST_TEST( di2.value() == 2 );
+ BOOST_TEST( di2.value() == 2 );
+ BOOST_TEST( di.value() == 0 );
+
+ cout << "Created MyDoubleInt objects.\n";
+
+ PRIVATE_EXPR_TEST( (di = di2), (di.value() == 2) );
+
+ BOOST_TEST( static_cast<bool>(di2 == di) );
+ BOOST_TEST( static_cast<bool>(2 == di) );
+ BOOST_TEST( static_cast<bool>(di == 2) );
+ BOOST_TEST( static_cast<bool>(di1 < di2) );
+ BOOST_TEST( static_cast<bool>(1 < di2) );
+ BOOST_TEST( static_cast<bool>(di1 <= di2) );
+ BOOST_TEST( static_cast<bool>(1 <= di2) );
+ BOOST_TEST( static_cast<bool>(di2 > di1) );
+ BOOST_TEST( static_cast<bool>(di2 > 1) );
+ BOOST_TEST( static_cast<bool>(di2 >= di1) );
+ BOOST_TEST( static_cast<bool>(di2 >= 1) );
+ BOOST_TEST( static_cast<bool>(di1 / di2 == half) );
+ BOOST_TEST( static_cast<bool>(di1 / 2 == half) );
+ BOOST_TEST( static_cast<bool>(1 / di2 == half) );
+ PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp/=2) == half) );
+ PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp/=di2) == half) );
+ BOOST_TEST( static_cast<bool>(di1 * di2 == di2) );
+ BOOST_TEST( static_cast<bool>(di1 * 2 == di2) );
+ BOOST_TEST( static_cast<bool>(1 * di2 == di2) );
+ PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp*=2) == di2) );
+ PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp*=di2) == di2) );
+ BOOST_TEST( static_cast<bool>(di2 - di1 == di1) );
+ BOOST_TEST( static_cast<bool>(di2 - 1 == di1) );
+ BOOST_TEST( static_cast<bool>(2 - di1 == di1) );
+ PRIVATE_EXPR_TEST( (tmp=di2), static_cast<bool>((tmp-=1) == di1) );
+ PRIVATE_EXPR_TEST( (tmp=di2), static_cast<bool>((tmp-=di1) == di1) );
+ BOOST_TEST( static_cast<bool>(di1 + di1 == di2) );
+ BOOST_TEST( static_cast<bool>(di1 + 1 == di2) );
+ BOOST_TEST( static_cast<bool>(1 + di1 == di2) );
+ PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp+=1) == di2) );
+ PRIVATE_EXPR_TEST( (tmp=di1), static_cast<bool>((tmp+=di1) == di2) );
+
+ cout << "Performed tests on MyDoubleInt objects.\n";
+
+ MyLongInt li1(1);
+ MyLongInt li2(2);
+ MyLongInt li;
+ MyLongInt tmp2;
+
+ BOOST_TEST( li1.value() == 1 );
+ BOOST_TEST( li2.value() == 2 );
+ BOOST_TEST( li.value() == 0 );
+
+ cout << "Created MyLongInt objects.\n";
+
+ PRIVATE_EXPR_TEST( (li = li2), (li.value() == 2) );
+
+ BOOST_TEST( static_cast<bool>(li2 == li) );
+ BOOST_TEST( static_cast<bool>(2 == li) );
+ BOOST_TEST( static_cast<bool>(li == 2) );
+ BOOST_TEST( static_cast<bool>(li1 < li2) );
+ BOOST_TEST( static_cast<bool>(1 < li2) );
+ BOOST_TEST( static_cast<bool>(li1 <= li2) );
+ BOOST_TEST( static_cast<bool>(1 <= li2) );
+ BOOST_TEST( static_cast<bool>(li2 > li1) );
+ BOOST_TEST( static_cast<bool>(li2 > 1) );
+ BOOST_TEST( static_cast<bool>(li2 >= li1) );
+ BOOST_TEST( static_cast<bool>(li2 >= 1) );
+ BOOST_TEST( static_cast<bool>(li1 % li2 == li1) );
+ BOOST_TEST( static_cast<bool>(li1 % 2 == li1) );
+ BOOST_TEST( static_cast<bool>(1 % li2 == li1) );
+ PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2%=2) == li1) );
+ PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2%=li2) == li1) );
+ BOOST_TEST( static_cast<bool>(li1 / li2 == 0) );
+ BOOST_TEST( static_cast<bool>(li1 / 2 == 0) );
+ BOOST_TEST( static_cast<bool>(1 / li2 == 0) );
+ PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2/=2) == 0) );
+ PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2/=li2) == 0) );
+ BOOST_TEST( static_cast<bool>(li1 * li2 == li2) );
+ BOOST_TEST( static_cast<bool>(li1 * 2 == li2) );
+ BOOST_TEST( static_cast<bool>(1 * li2 == li2) );
+ PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2*=2) == li2) );
+ PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2*=li2) == li2) );
+ BOOST_TEST( static_cast<bool>(li2 - li1 == li1) );
+ BOOST_TEST( static_cast<bool>(li2 - 1 == li1) );
+ BOOST_TEST( static_cast<bool>(2 - li1 == li1) );
+ PRIVATE_EXPR_TEST( (tmp2=li2), static_cast<bool>((tmp2-=1) == li1) );
+ PRIVATE_EXPR_TEST( (tmp2=li2), static_cast<bool>((tmp2-=li1) == li1) );
+ BOOST_TEST( static_cast<bool>(li1 + li1 == li2) );
+ BOOST_TEST( static_cast<bool>(li1 + 1 == li2) );
+ BOOST_TEST( static_cast<bool>(1 + li1 == li2) );
+ PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2+=1) == li2) );
+ PRIVATE_EXPR_TEST( (tmp2=li1), static_cast<bool>((tmp2+=li1) == li2) );
+
+ cout << "Performed tests on MyLongInt objects.\n";
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/utility/test/result_of_test.cpp b/src/boost/libs/utility/test/result_of_test.cpp
new file mode 100644
index 000000000..290043b37
--- /dev/null
+++ b/src/boost/libs/utility/test/result_of_test.cpp
@@ -0,0 +1,322 @@
+// Boost result_of library
+
+// Copyright Douglas Gregor 2003-2004. Use, modification and
+// distribution is subject to the Boost Software License, Version
+// 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+// Examples:
+// To run the default test:
+// $ cd libs/utility/test && bjam
+// To test decltype on g++ 2.7:
+// $ cd libs/utility/test && bjam cxxflags="-std=c++11 -D BOOST_RESULT_OF_USE_DECLTYPE"
+
+#include <boost/config.hpp>
+
+// For more information, see http://www.boost.org/libs/utility
+#include <boost/utility/result_of.hpp>
+#include <utility>
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+struct int_result_type
+{
+ typedef int result_type;
+ result_type operator()(float);
+};
+
+struct int_result_of
+{
+ template<typename F> struct result { typedef int type; };
+ result<int_result_of(double)>::type operator()(double);
+ result<const int_result_of(double)>::type operator()(double) const;
+ result<int_result_of()>::type operator()();
+ result<volatile int_result_of()>::type operator()() volatile;
+};
+
+struct int_result_type_and_float_result_of_and_char_return
+{
+ typedef int result_type;
+ template<typename F> struct result { typedef float type; };
+ char operator()(char);
+};
+
+template<typename T>
+struct int_result_type_template
+{
+ typedef int result_type;
+ result_type operator()(float);
+};
+
+template<typename T>
+struct int_result_of_template
+{
+ template<typename F> struct result;
+ template<typename This, typename That> struct result<This(That)> { typedef int type; };
+ typename result<int_result_of_template<T>(double)>::type operator()(double);
+ typename result<const int_result_of_template<T>(double)>::type operator()(double) const;
+ typename result<int_result_of_template<T>(double)>::type operator()();
+ typename result<volatile int_result_of_template<T>(double)>::type operator()() volatile;
+};
+
+template<typename T>
+struct int_result_type_and_float_result_of_and_char_return_template
+{
+ typedef int result_type;
+ template<typename F> struct result;
+ template<typename This, typename That> struct result<This(That)> { typedef float type; };
+ char operator()(char);
+};
+
+template<typename T>
+struct cv_overload_check {};
+
+struct result_of_member_function_template
+{
+ template<typename F> struct result;
+
+ template<typename This, typename That> struct result<This(That)> { typedef That type; };
+ template<class T> typename result<result_of_member_function_template(T)>::type operator()(T);
+
+ template<typename This, typename That> struct result<const This(That)> { typedef cv_overload_check<const That> type; };
+ template<class T> typename result<const result_of_member_function_template(T)>::type operator()(T) const;
+
+ template<typename This, typename That> struct result<volatile This(That)> { typedef cv_overload_check<volatile That> type; };
+ template<class T> typename result<volatile result_of_member_function_template(T)>::type operator()(T) volatile;
+
+ template<typename This, typename That> struct result<const volatile This(That)> { typedef cv_overload_check<const volatile That> type; };
+ template<class T> typename result<const volatile result_of_member_function_template(T)>::type operator()(T) const volatile;
+
+ template<typename This, typename That> struct result<This(That &, That)> { typedef That & type; };
+ template<class T> typename result<result_of_member_function_template(T &, T)>::type operator()(T &, T);
+
+ template<typename This, typename That> struct result<This(That const &, That)> { typedef That const & type; };
+ template<class T> typename result<result_of_member_function_template(T const &, T)>::type operator()(T const &, T);
+
+ template<typename This, typename That> struct result<This(That volatile &, That)> { typedef That volatile & type; };
+ template<class T> typename result<result_of_member_function_template(T volatile &, T)>::type operator()(T volatile &, T);
+
+ template<typename This, typename That> struct result<This(That const volatile &, That)> { typedef That const volatile & type; };
+ template<class T> typename result<result_of_member_function_template(T const volatile &, T)>::type operator()(T const volatile &, T);
+};
+
+struct no_result_type_or_result
+{
+ short operator()(double);
+ cv_overload_check<const short> operator()(double) const;
+ cv_overload_check<volatile short> operator()(double) volatile;
+ cv_overload_check<const volatile short> operator()(double) const volatile;
+ int operator()();
+ cv_overload_check<const int> operator()() const;
+ cv_overload_check<volatile int> operator()() volatile;
+ cv_overload_check<const volatile int> operator()() const volatile;
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ short operator()(int&&);
+ int operator()(int&);
+ long operator()(int const&);
+#endif
+};
+
+template<typename T>
+struct no_result_type_or_result_template
+{
+ short operator()(double);
+ cv_overload_check<const short> operator()(double) const;
+ cv_overload_check<volatile short> operator()(double) volatile;
+ cv_overload_check<const volatile short> operator()(double) const volatile;
+ int operator()();
+ cv_overload_check<const int> operator()() const;
+ cv_overload_check<volatile int> operator()() volatile;
+ cv_overload_check<const volatile int> operator()() const volatile;
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ short operator()(int&&);
+ int operator()(int&);
+ long operator()(int const&);
+#endif
+};
+
+// sfinae_tests are derived from example code from Joel de Guzman,
+// which demonstrated the interaction between result_of and SFINAE.
+template <typename F, typename Arg>
+typename boost::result_of<F(Arg const&)>::type
+sfinae_test(F f, Arg const& arg)
+{
+ return f(arg);
+}
+
+template <typename F, typename Arg>
+typename boost::result_of<F(Arg&)>::type
+sfinae_test(F f, Arg& arg)
+{
+ return f(arg);
+}
+
+int sfinae_test_f(int& i)
+{
+ return i;
+}
+
+struct X {};
+
+int main()
+{
+ using namespace boost;
+
+ typedef int (*func_ptr)(float, double);
+ typedef int (&func_ref)(float, double);
+ typedef int (*func_ptr_0)();
+ typedef int (&func_ref_0)();
+ typedef void (*func_ptr_void)(float, double);
+ typedef void (&func_ref_void)(float, double);
+ typedef void (*func_ptr_void_0)();
+ typedef void (&func_ref_void_0)();
+ typedef int (X::*mem_func_ptr)(float);
+ typedef int (X::*mem_func_ptr_c)(float) const;
+ typedef int (X::*mem_func_ptr_v)(float) volatile;
+ typedef int (X::*mem_func_ptr_cv)(float) const volatile;
+ typedef int (X::*mem_func_ptr_0)();
+
+ BOOST_STATIC_ASSERT((is_same<result_of<int_result_type(float)>::type, int>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<int_result_of(double)>::type, int>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<const int_result_of(double)>::type, int>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_template<void>(float)>::type, int>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<int_result_of_template<void>(double)>::type, int>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<const int_result_of_template<void>(double)>::type, int>::value));
+
+ BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_type(float)>::type, int>::value));
+ BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_of(double)>::type, int>::value));
+ BOOST_STATIC_ASSERT((is_same<tr1_result_of<const int_result_of(double)>::type, int>::value));
+ BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_type_template<void>(float)>::type, int>::value));
+ BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_of_template<void>(double)>::type, int>::value));
+ BOOST_STATIC_ASSERT((is_same<tr1_result_of<const int_result_of_template<void>(double)>::type, int>::value));
+
+ BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_of(void)>::type, void>::value));
+ BOOST_STATIC_ASSERT((is_same<tr1_result_of<volatile int_result_of(void)>::type, void>::value));
+ BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_of_template<void>(void)>::type, void>::value));
+ BOOST_STATIC_ASSERT((is_same<tr1_result_of<volatile int_result_of_template<void>(void)>::type, void>::value));
+
+ // Prior to decltype, result_of could not deduce the return type
+ // of nullary function objects unless they exposed a result_type.
+#if defined(BOOST_RESULT_OF_USE_DECLTYPE)
+ BOOST_STATIC_ASSERT((is_same<result_of<int_result_of(void)>::type, int>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<volatile int_result_of(void)>::type, int>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<int_result_of_template<void>(void)>::type, int>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<volatile int_result_of_template<void>(void)>::type, int>::value));
+#else
+ BOOST_STATIC_ASSERT((is_same<result_of<int_result_of(void)>::type, void>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<volatile int_result_of(void)>::type, void>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<int_result_of_template<void>(void)>::type, void>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<volatile int_result_of_template<void>(void)>::type, void>::value));
+#endif
+
+ // Prior to decltype, result_of ignored a nested result<> if
+ // result_type was defined. After decltype, result_of deduces the
+ // actual return type of the function object, ignoring both
+ // result<> and result_type.
+#if defined(BOOST_RESULT_OF_USE_DECLTYPE)
+ BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of_and_char_return(char)>::type, char>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of_and_char_return_template<void>(char)>::type, char>::value));
+#else
+ BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of_and_char_return(char)>::type, int>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<int_result_type_and_float_result_of_and_char_return_template<void>(char)>::type, int>::value));
+#endif
+
+ BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_type_and_float_result_of_and_char_return(char)>::type, int>::value));
+ BOOST_STATIC_ASSERT((is_same<tr1_result_of<int_result_type_and_float_result_of_and_char_return_template<void>(char)>::type, int>::value));
+
+ BOOST_STATIC_ASSERT((is_same<result_of<func_ptr(char, float)>::type, int>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<func_ref(char, float)>::type, int>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<func_ptr_0()>::type, int>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<func_ref_0()>::type, int>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<func_ptr_void(char, float)>::type, void>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<func_ref_void(char, float)>::type, void>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<func_ptr_void_0()>::type, void>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<func_ref_void_0()>::type, void>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr(X,char)>::type, int>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr_c(X,char)>::type, int>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr_v(X,char)>::type, int>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr_cv(X,char)>::type, int>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<mem_func_ptr_0(X)>::type, int>::value));
+
+ BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ptr(char, float)>::type, int>::value));
+ BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ref(char, float)>::type, int>::value));
+ BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ptr_0()>::type, int>::value));
+ BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ref_0()>::type, int>::value));
+ BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ptr_void(char, float)>::type, void>::value));
+ BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ref_void(char, float)>::type, void>::value));
+ BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ptr_void_0()>::type, void>::value));
+ BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ref_void_0()>::type, void>::value));
+ BOOST_STATIC_ASSERT((is_same<tr1_result_of<mem_func_ptr(X,char)>::type, int>::value));
+ BOOST_STATIC_ASSERT((is_same<tr1_result_of<mem_func_ptr_c(X,char)>::type, int>::value));
+ BOOST_STATIC_ASSERT((is_same<tr1_result_of<mem_func_ptr_v(X,char)>::type, int>::value));
+ BOOST_STATIC_ASSERT((is_same<tr1_result_of<mem_func_ptr_cv(X,char)>::type, int>::value));
+ BOOST_STATIC_ASSERT((is_same<tr1_result_of<mem_func_ptr_0(X)>::type, int>::value));
+ BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ptr(void)>::type, int>::value));
+ BOOST_STATIC_ASSERT((is_same<tr1_result_of<func_ref(void)>::type, int>::value));
+
+ BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(double)>::type, double>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<const result_of_member_function_template(double)>::type, cv_overload_check<const double> >::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<volatile result_of_member_function_template(double)>::type, cv_overload_check<volatile double> >::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<const volatile result_of_member_function_template(double)>::type, cv_overload_check<const volatile double> >::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(int &, int)>::type, int &>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(int const &, int)>::type, int const &>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(int volatile &, int)>::type, int volatile &>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<result_of_member_function_template(int const volatile &, int)>::type, int const volatile &>::value));
+
+ BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(double)>::type, double>::value));
+ BOOST_STATIC_ASSERT((is_same<tr1_result_of<const result_of_member_function_template(double)>::type, cv_overload_check<const double> >::value));
+ BOOST_STATIC_ASSERT((is_same<tr1_result_of<volatile result_of_member_function_template(double)>::type, cv_overload_check<volatile double> >::value));
+ BOOST_STATIC_ASSERT((is_same<tr1_result_of<const volatile result_of_member_function_template(double)>::type, cv_overload_check<const volatile double> >::value));
+ BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(int &, int)>::type, int &>::value));
+ BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(int const &, int)>::type, int const &>::value));
+ BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(int volatile &, int)>::type, int volatile &>::value));
+ BOOST_STATIC_ASSERT((is_same<tr1_result_of<result_of_member_function_template(int const volatile &, int)>::type, int const volatile &>::value));
+
+ typedef int (*pf_t)(int);
+ BOOST_STATIC_ASSERT((is_same<result_of<pf_t(int)>::type, int>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<pf_t const(int)>::type,int>::value));
+
+ BOOST_STATIC_ASSERT((is_same<tr1_result_of<pf_t(int)>::type, int>::value));
+ BOOST_STATIC_ASSERT((is_same<tr1_result_of<pf_t const(int)>::type,int>::value));
+
+#if defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK)
+ BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result(double)>::type, short>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<const no_result_type_or_result(double)>::type, cv_overload_check<const short> >::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<volatile no_result_type_or_result(double)>::type, cv_overload_check<volatile short> >::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<const volatile no_result_type_or_result(double)>::type, cv_overload_check<const volatile short> >::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result(void)>::type, int>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<const no_result_type_or_result(void)>::type, cv_overload_check<const int> >::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<volatile no_result_type_or_result(void)>::type, cv_overload_check<volatile int> >::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<const volatile no_result_type_or_result(void)>::type, cv_overload_check<const volatile int> >::value));
+
+ BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_template<void>(double)>::type, short>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<const no_result_type_or_result_template<void>(double)>::type, cv_overload_check<const short> >::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<volatile no_result_type_or_result_template<void>(double)>::type, cv_overload_check<volatile short> >::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<const volatile no_result_type_or_result_template<void>(double)>::type, cv_overload_check<const volatile short> >::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_template<void>(void)>::type, int>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<const no_result_type_or_result_template<void>(void)>::type, cv_overload_check<const int> >::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<volatile no_result_type_or_result_template<void>(void)>::type, cv_overload_check<volatile int> >::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<const volatile no_result_type_or_result_template<void>(void)>::type, cv_overload_check<const volatile int> >::value));
+
+ BOOST_STATIC_ASSERT((is_same<result_of<func_ptr&(char, float)>::type, int>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<func_ptr const&(char, float)>::type, int>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<int_result_of&(double)>::type, int>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<int_result_of const&(double)>::type, int>::value));
+
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+ BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result(int&&)>::type, short>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result(int&)>::type, int>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result(int const&)>::type, long>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_template<void>(int&&)>::type, short>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_template<void>(int&)>::type, int>::value));
+ BOOST_STATIC_ASSERT((is_same<result_of<no_result_type_or_result_template<void>(int const&)>::type, long>::value));
+#endif
+#endif
+
+#if defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK)
+ int i = 123;
+ sfinae_test(sfinae_test_f, i);
+#endif // defined(BOOST_RESULT_OF_USE_DECLTYPE) || defined(BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK)
+
+ return 0;
+}
diff --git a/src/boost/libs/utility/test/string_ref_from_rvalue.cpp b/src/boost/libs/utility/test/string_ref_from_rvalue.cpp
new file mode 100644
index 000000000..6ec8a5a2d
--- /dev/null
+++ b/src/boost/libs/utility/test/string_ref_from_rvalue.cpp
@@ -0,0 +1,26 @@
+/*
+ Copyright (c) Marshall Clow 2017.
+
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+ For more information, see http://www.boost.org
+*/
+
+#include <iostream>
+#include <algorithm>
+#include <string>
+
+#include <boost/utility/string_ref.hpp>
+
+#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
+#error "Unsupported test"
+#endif
+
+std::string makeatemp() { return "abc"; }
+
+int main()
+{
+ boost::basic_string_ref<char> sv(makeatemp());
+ return 0;
+}
diff --git a/src/boost/libs/utility/test/string_ref_test1.cpp b/src/boost/libs/utility/test/string_ref_test1.cpp
new file mode 100644
index 000000000..fc8890515
--- /dev/null
+++ b/src/boost/libs/utility/test/string_ref_test1.cpp
@@ -0,0 +1,110 @@
+/*
+ Copyright (c) Marshall Clow 2012-2012.
+
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+ For more information, see http://www.boost.org
+*/
+
+#include <iostream>
+#include <algorithm>
+#include <string>
+
+#include <boost/utility/string_ref.hpp>
+
+#include <boost/core/lightweight_test.hpp>
+
+typedef boost::string_ref string_ref;
+
+// Should be equal
+void interop ( const std::string &str, string_ref ref ) {
+// BOOST_TEST ( str == ref );
+ BOOST_TEST ( str.size () == ref.size ());
+ BOOST_TEST ( std::equal ( str.begin (), str.end (), ref.begin ()));
+ BOOST_TEST ( std::equal ( str.rbegin (), str.rend (), ref.rbegin ()));
+ }
+
+void null_tests ( const char *p ) {
+// All zero-length string-refs should be equal
+ string_ref sr1; // NULL, 0
+ string_ref sr2 ( NULL, 0 );
+ string_ref sr3 ( p, 0 );
+ string_ref sr4 ( p );
+ sr4.clear ();
+
+ BOOST_TEST ( sr1 == sr2 );
+ BOOST_TEST ( sr1 == sr3 );
+ BOOST_TEST ( sr2 == sr3 );
+ BOOST_TEST ( sr1 == sr4 );
+ }
+
+// make sure that substrings work just like strings
+void test_substr ( const std::string &str ) {
+ const size_t sz = str.size ();
+ string_ref ref ( str );
+
+// Substrings at the end
+ for ( size_t i = 0; i <= sz; ++ i )
+ interop ( str.substr ( i ), ref.substr ( i ));
+
+// Substrings at the beginning
+ for ( size_t i = 0; i <= sz; ++ i )
+ interop ( str.substr ( 0, i ), ref.substr ( 0, i ));
+
+// All possible substrings
+ for ( size_t i = 0; i < sz; ++i )
+ for ( size_t j = i; j < sz; ++j )
+ interop ( str.substr ( i, j ), ref.substr ( i, j ));
+ }
+
+// make sure that removing prefixes and suffixes work just like strings
+void test_remove ( const std::string &str ) {
+ const size_t sz = str.size ();
+ std::string work;
+ string_ref ref;
+
+ for ( size_t i = 1; i <= sz; ++i ) {
+ work = str;
+ ref = str;
+ while ( ref.size () >= i ) {
+ interop ( work, ref );
+ work.erase ( 0, i );
+ ref.remove_prefix (i);
+ }
+ }
+
+ for ( size_t i = 1; i < sz; ++ i ) {
+ work = str;
+ ref = str;
+ while ( ref.size () >= i ) {
+ interop ( work, ref );
+ work.erase ( work.size () - i, i );
+ ref.remove_suffix (i);
+ }
+ }
+ }
+
+const char *test_strings [] = {
+ "",
+ "1",
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
+ "0123456789",
+ NULL
+ };
+
+int main()
+{
+ const char **p = &test_strings[0];
+
+ while ( *p != NULL ) {
+ interop ( *p, *p );
+ test_substr ( *p );
+ test_remove ( *p );
+ null_tests ( *p );
+
+ p++;
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/utility/test/string_ref_test2.cpp b/src/boost/libs/utility/test/string_ref_test2.cpp
new file mode 100644
index 000000000..d73377517
--- /dev/null
+++ b/src/boost/libs/utility/test/string_ref_test2.cpp
@@ -0,0 +1,323 @@
+/*
+ Copyright (c) Marshall Clow 2012-2012.
+
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+ For more information, see http://www.boost.org
+*/
+
+#include <iostream>
+#include <cstring> // for std::strchr
+
+#include <boost/utility/string_ref.hpp>
+
+#include <boost/core/lightweight_test.hpp>
+
+typedef boost::string_ref string_ref;
+
+void ends_with ( const char *arg ) {
+ const size_t sz = std::strlen ( arg );
+ string_ref sr ( arg );
+ string_ref sr2 ( arg );
+ const char *p = arg;
+
+ while ( *p ) {
+ BOOST_TEST ( sr.ends_with ( p ));
+ ++p;
+ }
+
+ while ( !sr2.empty ()) {
+ BOOST_TEST ( sr.ends_with ( sr2 ));
+ sr2.remove_prefix (1);
+ }
+
+ sr2 = arg;
+ while ( !sr2.empty ()) {
+ BOOST_TEST ( sr.ends_with ( sr2 ));
+ sr2.remove_prefix (1);
+ }
+
+ char ch = sz == 0 ? '\0' : arg [ sz - 1 ];
+ sr2 = arg;
+ if ( sz > 0 )
+ BOOST_TEST ( sr2.ends_with ( ch ));
+ BOOST_TEST ( !sr2.ends_with ( ++ch ));
+ BOOST_TEST ( sr2.ends_with ( string_ref ()));
+ }
+
+void starts_with ( const char *arg ) {
+ const size_t sz = std::strlen ( arg );
+ string_ref sr ( arg );
+ string_ref sr2 ( arg );
+ const char *p = arg + std::strlen ( arg ) - 1;
+ while ( p >= arg ) {
+ std::string foo ( arg, p + 1 );
+ BOOST_TEST ( sr.starts_with ( foo ));
+ --p;
+ }
+
+ while ( !sr2.empty ()) {
+ BOOST_TEST ( sr.starts_with ( sr2 ));
+ sr2.remove_suffix (1);
+ }
+
+ char ch = *arg;
+ sr2 = arg;
+ if ( sz > 0 )
+ BOOST_TEST ( sr2.starts_with ( ch ));
+ BOOST_TEST ( !sr2.starts_with ( ++ch ));
+ BOOST_TEST ( sr2.starts_with ( string_ref ()));
+ }
+
+void reverse ( const char *arg ) {
+// Round trip
+ string_ref sr1 ( arg );
+ std::string string1 ( sr1.rbegin (), sr1.rend ());
+ string_ref sr2 ( string1 );
+ std::string string2 ( sr2.rbegin (), sr2.rend ());
+
+ BOOST_TEST ( std::equal ( sr2.rbegin (), sr2.rend (), arg ));
+ BOOST_TEST ( string2 == arg );
+ BOOST_TEST ( std::equal ( sr1.begin (), sr1.end (), string2.begin ()));
+ }
+
+// This helper function eliminates signed vs. unsigned warnings
+string_ref::size_type ptr_diff ( const char *res, const char *base ) {
+ BOOST_TEST ( res >= base );
+ return static_cast<string_ref::size_type> ( res - base );
+ }
+
+void find ( const char *arg ) {
+ string_ref sr1;
+ string_ref sr2;
+ const char *p;
+
+// When we search for the empty string, we find it at position 0
+ BOOST_TEST ( sr1.find (sr2) == 0 );
+ BOOST_TEST ( sr1.rfind(sr2) == 0 );
+
+// Look for each character in the string(searching from the start)
+ p = arg;
+ sr1 = arg;
+ while ( *p ) {
+ string_ref::size_type pos = sr1.find(*p);
+ BOOST_TEST ( pos != string_ref::npos && ( pos <= ptr_diff ( p, arg )));
+ ++p;
+ }
+
+// Look for each character in the string (searching from the end)
+ p = arg;
+ sr1 = arg;
+ while ( *p ) {
+ string_ref::size_type pos = sr1.rfind(*p);
+ BOOST_TEST ( pos != string_ref::npos && pos < sr1.size () && ( pos >= ptr_diff ( p, arg )));
+ ++p;
+ }
+
+// Look for pairs on characters (searching from the start)
+ sr1 = arg;
+ p = arg;
+ while ( *p && *(p+1)) {
+ string_ref sr3 ( p, 2 );
+ string_ref::size_type pos = sr1.find ( sr3 );
+ BOOST_TEST ( pos != string_ref::npos && pos <= static_cast<string_ref::size_type>( p - arg ));
+ p++;
+ }
+
+ sr1 = arg;
+ p = arg;
+// for all possible chars, see if we find them in the right place.
+// Note that strchr will/might do the _wrong_ thing if we search for NULL
+ for ( int ch = 1; ch < 256; ++ch ) {
+ string_ref::size_type pos = sr1.find(ch);
+ const char *strp = std::strchr ( arg, ch );
+ BOOST_TEST (( strp == NULL ) == ( pos == string_ref::npos ));
+ if ( strp != NULL )
+ BOOST_TEST ( ptr_diff ( strp, arg ) == pos );
+ }
+
+ sr1 = arg;
+ p = arg;
+// for all possible chars, see if we find them in the right place.
+// Note that strchr will/might do the _wrong_ thing if we search for NULL
+ for ( int ch = 1; ch < 256; ++ch ) {
+ string_ref::size_type pos = sr1.rfind(ch);
+ const char *strp = std::strrchr ( arg, ch );
+ BOOST_TEST (( strp == NULL ) == ( pos == string_ref::npos ));
+ if ( strp != NULL )
+ BOOST_TEST ( ptr_diff ( strp, arg ) == pos );
+ }
+
+
+// Find everything at the start
+ p = arg;
+ sr1 = arg;
+ while ( !sr1.empty ()) {
+ string_ref::size_type pos = sr1.find(*p);
+ BOOST_TEST ( pos == 0 );
+ sr1.remove_prefix (1);
+ ++p;
+ }
+
+// Find everything at the end
+ sr1 = arg;
+ p = arg + std::strlen ( arg ) - 1;
+ while ( !sr1.empty ()) {
+ string_ref::size_type pos = sr1.rfind(*p);
+ BOOST_TEST ( pos == sr1.size () - 1 );
+ sr1.remove_suffix (1);
+ --p;
+ }
+
+// Find everything at the start
+ sr1 = arg;
+ p = arg;
+ while ( !sr1.empty ()) {
+ string_ref::size_type pos = sr1.find_first_of(*p);
+ BOOST_TEST ( pos == 0 );
+ sr1.remove_prefix (1);
+ ++p;
+ }
+
+
+// Find everything at the end
+ sr1 = arg;
+ p = arg + std::strlen ( arg ) - 1;
+ while ( !sr1.empty ()) {
+ string_ref::size_type pos = sr1.find_last_of(*p);
+ BOOST_TEST ( pos == sr1.size () - 1 );
+ sr1.remove_suffix (1);
+ --p;
+ }
+
+// Basic sanity checking for "find_first_of / find_first_not_of"
+ sr1 = arg;
+ sr2 = arg;
+ while ( !sr1.empty() ) {
+ BOOST_TEST ( sr1.find_first_of ( sr2 ) == 0 );
+ BOOST_TEST ( sr1.find_first_not_of ( sr2 ) == string_ref::npos );
+ sr1.remove_prefix ( 1 );
+ }
+
+ p = arg;
+ sr1 = arg;
+ while ( *p ) {
+ string_ref::size_type pos1 = sr1.find_first_of(*p);
+ string_ref::size_type pos2 = sr1.find_first_not_of(*p);
+ BOOST_TEST ( pos1 != string_ref::npos && pos1 < sr1.size () && pos1 <= ptr_diff ( p, arg ));
+ if ( pos2 != string_ref::npos ) {
+ for ( size_t i = 0 ; i < pos2; ++i )
+ BOOST_TEST ( sr1[i] == *p );
+ BOOST_TEST ( sr1 [ pos2 ] != *p );
+ }
+
+ BOOST_TEST ( pos2 != pos1 );
+ ++p;
+ }
+
+// Basic sanity checking for "find_last_of / find_last_not_of"
+ sr1 = arg;
+ sr2 = arg;
+ while ( !sr1.empty() ) {
+ BOOST_TEST ( sr1.find_last_of ( sr2 ) == ( sr1.size () - 1 ));
+ BOOST_TEST ( sr1.find_last_not_of ( sr2 ) == string_ref::npos );
+ sr1.remove_suffix ( 1 );
+ }
+
+ p = arg;
+ sr1 = arg;
+ while ( *p ) {
+ string_ref::size_type pos1 = sr1.find_last_of(*p);
+ string_ref::size_type pos2 = sr1.find_last_not_of(*p);
+ BOOST_TEST ( pos1 != string_ref::npos && pos1 < sr1.size () && pos1 >= ptr_diff ( p, arg ));
+ BOOST_TEST ( pos2 == string_ref::npos || pos1 < sr1.size ());
+ if ( pos2 != string_ref::npos ) {
+ for ( size_t i = sr1.size () -1 ; i > pos2; --i )
+ BOOST_TEST ( sr1[i] == *p );
+ BOOST_TEST ( sr1 [ pos2 ] != *p );
+ }
+
+ BOOST_TEST ( pos2 != pos1 );
+ ++p;
+ }
+
+ }
+
+
+void to_string ( const char *arg ) {
+ string_ref sr1;
+ std::string str1;
+ std::string str2;
+
+ str1.assign ( arg );
+ sr1 = arg;
+// str2 = sr1.to_string<std::allocator<char> > ();
+ str2 = sr1.to_string ();
+ BOOST_TEST ( str1 == str2 );
+
+#ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
+ std::string str3 = static_cast<std::string> ( sr1 );
+ BOOST_TEST ( str1 == str3 );
+#endif
+ }
+
+void compare ( const char *arg ) {
+ string_ref sr1;
+ std::string str1;
+ std::string str2 = str1;
+
+ str1.assign ( arg );
+ sr1 = arg;
+ BOOST_TEST ( sr1 == sr1); // compare string_ref and string_ref
+ BOOST_TEST ( sr1 == str1); // compare string and string_ref
+ BOOST_TEST ( str1 == sr1 ); // compare string_ref and string
+ BOOST_TEST ( sr1 == arg ); // compare string_ref and pointer
+ BOOST_TEST ( arg == sr1 ); // compare pointer and string_ref
+
+ if ( sr1.size () > 0 ) {
+ (*str1.rbegin())++;
+ BOOST_TEST ( sr1 != str1 );
+ BOOST_TEST ( str1 != sr1 );
+ BOOST_TEST ( sr1 < str1 );
+ BOOST_TEST ( sr1 <= str1 );
+ BOOST_TEST ( str1 > sr1 );
+ BOOST_TEST ( str1 >= sr1 );
+
+ (*str1.rbegin()) -= 2;
+ BOOST_TEST ( sr1 != str1 );
+ BOOST_TEST ( str1 != sr1 );
+ BOOST_TEST ( sr1 > str1 );
+ BOOST_TEST ( sr1 >= str1 );
+ BOOST_TEST ( str1 < sr1 );
+ BOOST_TEST ( str1 <= sr1 );
+ }
+ }
+
+const char *test_strings [] = {
+ "",
+ "0",
+ "abc",
+ "AAA", // all the same
+ "adsfadadiaef;alkdg;aljt;j agl;sjrl;tjs;lga;lretj;srg[w349u5209dsfadfasdfasdfadsf",
+ "abc\0asdfadsfasf",
+ NULL
+ };
+
+int main()
+{
+ const char **p = &test_strings[0];
+
+ while ( *p != NULL ) {
+ starts_with ( *p );
+ ends_with ( *p );
+ reverse ( *p );
+ find ( *p );
+ to_string ( *p );
+ compare ( *p );
+
+ p++;
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/utility/test/string_ref_test_io.cpp b/src/boost/libs/utility/test/string_ref_test_io.cpp
new file mode 100644
index 000000000..3609f915f
--- /dev/null
+++ b/src/boost/libs/utility/test/string_ref_test_io.cpp
@@ -0,0 +1,184 @@
+/*
+ * Copyright Andrey Semashev 2013.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file string_ref_test_io.cpp
+ * \author Andrey Semashev
+ * \date 26.05.2013
+ *
+ * \brief This header contains tests for stream operations of \c basic_string_ref.
+ */
+
+#include <boost/utility/string_ref.hpp>
+
+#include <iomanip>
+#include <sstream>
+#include <algorithm>
+#include <iterator>
+#include <string>
+
+#include <boost/config.hpp>
+#include <boost/core/lightweight_test.hpp>
+
+/* Current implementations seem to be missing codecvt facets to convert chars to char16_t and char32_t even though the types are available.
+*/
+
+static const char* test_strings[] =
+{
+ "begin",
+ "abcd",
+ "end"
+};
+
+//! The context with test data for particular character type
+template< typename CharT >
+struct context
+{
+ typedef CharT char_type;
+ typedef std::basic_string< char_type > string_type;
+ typedef std::basic_ostringstream< char_type > ostream_type;
+
+ string_type begin, abcd, end;
+
+ context()
+ {
+ boost::string_ref str = test_strings[0];
+ std::copy(str.begin(), str.end(), std::back_inserter(begin));
+
+ str = test_strings[1];
+ std::copy(str.begin(), str.end(), std::back_inserter(abcd));
+
+ str = test_strings[2];
+ std::copy(str.begin(), str.end(), std::back_inserter(end));
+ }
+};
+
+// Test regular output
+template<class CharT>
+void test_string_ref_output()
+{
+ typedef CharT char_type;
+ typedef std::basic_ostringstream< char_type > ostream_type;
+ typedef boost::basic_string_ref< char_type > string_ref_type;
+
+ context< char_type > ctx;
+
+ ostream_type strm;
+ strm << string_ref_type(ctx.abcd);
+ BOOST_TEST(strm.str() == ctx.abcd);
+}
+
+// Test support for padding
+template<class CharT>
+void test_padding()
+{
+ typedef CharT char_type;
+ typedef std::basic_ostringstream< char_type > ostream_type;
+ typedef boost::basic_string_ref< char_type > string_ref_type;
+
+ context< char_type > ctx;
+
+ // Test for padding
+ {
+ ostream_type strm_ref;
+ strm_ref << ctx.begin << std::setw(8) << string_ref_type(ctx.abcd) << ctx.end;
+
+ ostream_type strm_correct;
+ strm_correct << ctx.begin << std::setw(8) << ctx.abcd << ctx.end;
+
+ BOOST_TEST(strm_ref.str() == strm_correct.str());
+ }
+
+ // Test for long padding
+ {
+ ostream_type strm_ref;
+ strm_ref << ctx.begin << std::setw(100) << string_ref_type(ctx.abcd) << ctx.end;
+
+ ostream_type strm_correct;
+ strm_correct << ctx.begin << std::setw(100) << ctx.abcd << ctx.end;
+
+ BOOST_TEST(strm_ref.str() == strm_correct.str());
+ }
+
+ // Test that short width does not truncate the string
+ {
+ ostream_type strm_ref;
+ strm_ref << ctx.begin << std::setw(1) << string_ref_type(ctx.abcd) << ctx.end;
+
+ ostream_type strm_correct;
+ strm_correct << ctx.begin << std::setw(1) << ctx.abcd << ctx.end;
+
+ BOOST_TEST(strm_ref.str() == strm_correct.str());
+ }
+}
+
+// Test support for padding fill
+template<class CharT>
+void test_padding_fill()
+{
+ typedef CharT char_type;
+ typedef std::basic_ostringstream< char_type > ostream_type;
+ typedef boost::basic_string_ref< char_type > string_ref_type;
+
+ context< char_type > ctx;
+
+ ostream_type strm_ref;
+ strm_ref << ctx.begin << std::setfill(static_cast< char_type >('x')) << std::setw(8) << string_ref_type(ctx.abcd) << ctx.end;
+
+ ostream_type strm_correct;
+ strm_correct << ctx.begin << std::setfill(static_cast< char_type >('x')) << std::setw(8) << ctx.abcd << ctx.end;
+
+ BOOST_TEST(strm_ref.str() == strm_correct.str());
+}
+
+// Test support for alignment
+template<class CharT>
+void test_alignment()
+{
+ typedef CharT char_type;
+ typedef std::basic_ostringstream< char_type > ostream_type;
+ typedef boost::basic_string_ref< char_type > string_ref_type;
+
+ context< char_type > ctx;
+
+ // Left alignment
+ {
+ ostream_type strm_ref;
+ strm_ref << ctx.begin << std::left << std::setw(8) << string_ref_type(ctx.abcd) << ctx.end;
+
+ ostream_type strm_correct;
+ strm_correct << ctx.begin << std::left << std::setw(8) << ctx.abcd << ctx.end;
+
+ BOOST_TEST(strm_ref.str() == strm_correct.str());
+ }
+
+ // Right alignment
+ {
+ ostream_type strm_ref;
+ strm_ref << ctx.begin << std::right << std::setw(8) << string_ref_type(ctx.abcd) << ctx.end;
+
+ ostream_type strm_correct;
+ strm_correct << ctx.begin << std::right << std::setw(8) << ctx.abcd << ctx.end;
+
+ BOOST_TEST(strm_ref.str() == strm_correct.str());
+ }
+}
+
+template<class CharT>
+void test()
+{
+ test_string_ref_output<CharT>();
+ test_padding<CharT>();
+ test_padding_fill<CharT>();
+ test_alignment<CharT>();
+}
+
+int main()
+{
+ test<char>();
+ test<wchar_t>();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/utility/test/string_view_constexpr_test1.cpp b/src/boost/libs/utility/test/string_view_constexpr_test1.cpp
new file mode 100644
index 000000000..d116e12d6
--- /dev/null
+++ b/src/boost/libs/utility/test/string_view_constexpr_test1.cpp
@@ -0,0 +1,115 @@
+/*
+ Copyright (c) Marshall Clow 2017-2017.
+
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+ For more information, see http://www.boost.org
+*/
+
+#include <new> // for placement new
+#include <iostream>
+#include <cstddef> // for NULL, std::size_t, std::ptrdiff_t
+#include <cstring> // for std::strchr and std::strcmp
+#include <cstdlib> // for std::malloc and std::free
+#include <cstdio> // for EOF
+
+#include <boost/config.hpp>
+#include <boost/utility/string_view.hpp>
+
+#if __cplusplus >= 201402L
+struct constexpr_char_traits
+{
+ typedef char char_type;
+ typedef int int_type;
+ typedef std::streamoff off_type;
+ typedef std::streampos pos_type;
+ typedef std::mbstate_t state_type;
+
+ static void assign(char_type& c1, const char_type& c2) noexcept { c1 = c2; }
+ static constexpr bool eq(char_type c1, char_type c2) noexcept { return c1 == c2; }
+ static constexpr bool lt(char_type c1, char_type c2) noexcept { return c1 < c2; }
+
+ static constexpr int compare(const char_type* s1, const char_type* s2, size_t n) noexcept;
+ static constexpr size_t length(const char_type* s) noexcept;
+ static constexpr const char_type* find(const char_type* s, size_t n, const char_type& a) noexcept;
+ static constexpr char_type* move(char_type* s1, const char_type* s2, size_t n) noexcept;
+ static constexpr char_type* copy(char_type* s1, const char_type* s2, size_t n) noexcept;
+ static constexpr char_type* assign(char_type* s, size_t n, char_type a) noexcept;
+
+ static constexpr int_type not_eof(int_type c) noexcept { return eq_int_type(c, eof()) ? ~eof() : c; }
+ static constexpr char_type to_char_type(int_type c) noexcept { return char_type(c); }
+ static constexpr int_type to_int_type(char_type c) noexcept { return int_type(c); }
+ static constexpr bool eq_int_type(int_type c1, int_type c2) noexcept { return c1 == c2; }
+ static constexpr int_type eof() noexcept { return EOF; }
+};
+
+// yields:
+// 0 if for each i in [0,n), X::eq(s1[i],s2[i]) is true;
+// else, a negative value if, for some j in [0,n), X::lt(s1[j],s2[j]) is true and
+// for each i in [0,j) X::eq(s2[i],s2[i]) is true;
+// else a positive value.
+constexpr int constexpr_char_traits::compare(const char_type* s1, const char_type* s2, size_t n) noexcept
+{
+ for (; n != 0; --n, ++s1, ++s2)
+ {
+ if (lt(*s1, *s2))
+ return -1;
+ if (lt(*s2, *s1))
+ return 1;
+ }
+ return 0;
+}
+
+// yields: the smallest i such that X::eq(s[i],charT()) is true.
+constexpr size_t constexpr_char_traits::length(const char_type* s) noexcept
+{
+ size_t len = 0;
+ for (; !eq(*s, char_type(0)); ++s)
+ ++len;
+ return len;
+}
+
+typedef boost::basic_string_view<char, constexpr_char_traits> string_view;
+
+int main()
+{
+ constexpr string_view sv1;
+ constexpr string_view sv2{"abc", 3}; // ptr, len
+ constexpr string_view sv3{"def"}; // ptr
+
+ constexpr const char *s1 = "";
+ constexpr const char *s2 = "abc";
+
+ static_assert( (sv1 == sv1), "" );
+
+ static_assert(!(sv1 == sv2), "" );
+ static_assert( (sv1 != sv2), "" );
+ static_assert( (sv1 < sv2), "" );
+ static_assert( (sv1 <= sv2), "" );
+ static_assert(!(sv1 > sv2), "" );
+ static_assert(!(sv1 >= sv2), "" );
+
+ static_assert(!(s1 == sv2), "" );
+ static_assert( (s1 != sv2), "" );
+ static_assert( (s1 < sv2), "" );
+ static_assert( (s1 <= sv2), "" );
+ static_assert(!(s1 > sv2), "" );
+ static_assert(!(s1 >= sv2), "" );
+
+ static_assert(!(sv1 == s2), "" );
+ static_assert( (sv1 != s2), "" );
+ static_assert( (sv1 < s2), "" );
+ static_assert( (sv1 <= s2), "" );
+ static_assert(!(sv1 > s2), "" );
+ static_assert(!(sv1 >= s2), "" );
+
+ static_assert( sv1.compare(sv2) < 0, "" );
+ static_assert( sv1.compare(sv1) == 0, "" );
+ static_assert( sv3.compare(sv1) > 0, "" );
+
+ static_assert( sv1.compare(s2) < 0, "" );
+ static_assert( sv1.compare(s1) == 0, "" );
+ static_assert( sv3.compare(s1) > 0, "" );
+}
+#endif
diff --git a/src/boost/libs/utility/test/string_view_from_rvalue.cpp b/src/boost/libs/utility/test/string_view_from_rvalue.cpp
new file mode 100644
index 000000000..a76493959
--- /dev/null
+++ b/src/boost/libs/utility/test/string_view_from_rvalue.cpp
@@ -0,0 +1,26 @@
+/*
+ Copyright (c) Marshall Clow 2017.
+
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+ For more information, see http://www.boost.org
+*/
+
+#include <iostream>
+#include <algorithm>
+#include <string>
+
+#include <boost/utility/string_view.hpp>
+
+#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
+#error "Unsupported test"
+#endif
+
+std::string makeatemp() { return "abc"; }
+
+int main()
+{
+ boost::basic_string_view<char> sv(makeatemp());
+ return 0;
+}
diff --git a/src/boost/libs/utility/test/string_view_test1.cpp b/src/boost/libs/utility/test/string_view_test1.cpp
new file mode 100644
index 000000000..c35bbfac6
--- /dev/null
+++ b/src/boost/libs/utility/test/string_view_test1.cpp
@@ -0,0 +1,120 @@
+/*
+ Copyright (c) Marshall Clow 2012-2012.
+
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+ For more information, see http://www.boost.org
+*/
+
+#include <iostream>
+#include <algorithm>
+#include <string>
+
+#include <boost/utility/string_view.hpp>
+#include <boost/container_hash/hash.hpp>
+
+#include <boost/core/lightweight_test.hpp>
+
+typedef boost::string_view string_view;
+
+// Should be equal
+void interop ( const std::string &str, string_view ref ) {
+// BOOST_TEST ( str == ref );
+ BOOST_TEST ( str.size () == ref.size ());
+ BOOST_TEST ( std::equal ( str.begin (), str.end (), ref.begin ()));
+ BOOST_TEST ( std::equal ( str.rbegin (), str.rend (), ref.rbegin ()));
+ }
+
+void null_tests ( const char *p ) {
+// All zero-length string-refs should be equal
+ string_view sr1; // NULL, 0
+ string_view sr2 ( NULL, 0 );
+ string_view sr3 ( p, 0 );
+ string_view sr4 ( p );
+ sr4.clear ();
+
+ BOOST_TEST ( sr1 == sr2 );
+ BOOST_TEST ( sr1 == sr3 );
+ BOOST_TEST ( sr2 == sr3 );
+ BOOST_TEST ( sr1 == sr4 );
+ }
+
+// make sure that substrings work just like strings
+void test_substr ( const std::string &str ) {
+ const size_t sz = str.size ();
+ string_view ref ( str );
+
+// Substrings at the end
+ for ( size_t i = 0; i <= sz; ++ i )
+ interop ( str.substr ( i ), ref.substr ( i ));
+
+// Substrings at the beginning
+ for ( size_t i = 0; i <= sz; ++ i )
+ interop ( str.substr ( 0, i ), ref.substr ( 0, i ));
+
+// All possible substrings
+ for ( size_t i = 0; i < sz; ++i )
+ for ( size_t j = i; j < sz; ++j )
+ interop ( str.substr ( i, j ), ref.substr ( i, j ));
+ }
+
+// make sure that removing prefixes and suffixes work just like strings
+void test_remove ( const std::string &str ) {
+ const size_t sz = str.size ();
+ std::string work;
+ string_view ref;
+
+ for ( size_t i = 1; i <= sz; ++i ) {
+ work = str;
+ ref = str;
+ while ( ref.size () >= i ) {
+ interop ( work, ref );
+ work.erase ( 0, i );
+ ref.remove_prefix (i);
+ }
+ }
+
+ for ( size_t i = 1; i < sz; ++ i ) {
+ work = str;
+ ref = str;
+ while ( ref.size () >= i ) {
+ interop ( work, ref );
+ work.erase ( work.size () - i, i );
+ ref.remove_suffix (i);
+ }
+ }
+ }
+
+void test_hash(const std::string& str) {
+ string_view ref = str;
+ BOOST_TEST(boost::hash_value(ref) == boost::hash_value(str));
+ boost::hash<std::string> hstr;
+ boost::hash<string_view> hsv;
+ BOOST_TEST(hsv(ref) == hstr(str));
+ }
+
+const char *test_strings [] = {
+ "",
+ "1",
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
+ "0123456789",
+ NULL
+ };
+
+int main()
+{
+ const char **p = &test_strings[0];
+
+ while ( *p != NULL ) {
+ interop ( *p, *p );
+ test_substr ( *p );
+ test_remove ( *p );
+ null_tests ( *p );
+ test_hash( *p );
+
+ p++;
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/utility/test/string_view_test2.cpp b/src/boost/libs/utility/test/string_view_test2.cpp
new file mode 100644
index 000000000..135fd1aa3
--- /dev/null
+++ b/src/boost/libs/utility/test/string_view_test2.cpp
@@ -0,0 +1,410 @@
+/*
+ Copyright (c) Marshall Clow 2012-2012.
+
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+ For more information, see http://www.boost.org
+*/
+
+#include <new> // for placement new
+#include <iostream>
+#include <cstddef> // for NULL, std::size_t, std::ptrdiff_t
+#include <cstring> // for std::strchr and std::strcmp
+#include <cstdlib> // for std::malloc and std::free
+
+#include <boost/utility/string_view.hpp>
+#include <boost/config.hpp>
+
+#include <boost/core/lightweight_test.hpp>
+
+typedef boost::string_view string_view;
+
+void ends_with ( const char *arg ) {
+ const size_t sz = std::strlen ( arg );
+ string_view sr ( arg );
+ string_view sr2 ( arg );
+ const char *p = arg;
+
+ while ( *p ) {
+ BOOST_TEST ( sr.ends_with ( p ));
+ ++p;
+ }
+
+ while ( !sr2.empty ()) {
+ BOOST_TEST ( sr.ends_with ( sr2 ));
+ sr2.remove_prefix (1);
+ }
+
+ sr2 = arg;
+ while ( !sr2.empty ()) {
+ BOOST_TEST ( sr.ends_with ( sr2 ));
+ sr2.remove_prefix (1);
+ }
+
+ char ch = sz == 0 ? '\0' : arg [ sz - 1 ];
+ sr2 = arg;
+ if ( sz > 0 )
+ BOOST_TEST ( sr2.ends_with ( ch ));
+ BOOST_TEST ( !sr2.ends_with ( ++ch ));
+ BOOST_TEST ( sr2.ends_with ( string_view()));
+ }
+
+void starts_with ( const char *arg ) {
+ const size_t sz = std::strlen ( arg );
+ string_view sr ( arg );
+ string_view sr2 ( arg );
+ const char *p = arg + std::strlen ( arg ) - 1;
+ while ( p >= arg ) {
+ std::string foo ( arg, p + 1 );
+ BOOST_TEST ( sr.starts_with ( foo ));
+ --p;
+ }
+
+ while ( !sr2.empty ()) {
+ BOOST_TEST ( sr.starts_with ( sr2 ));
+ sr2.remove_suffix (1);
+ }
+
+ char ch = *arg;
+ sr2 = arg;
+ if ( sz > 0 )
+ BOOST_TEST ( sr2.starts_with ( ch ));
+ BOOST_TEST ( !sr2.starts_with ( ++ch ));
+ BOOST_TEST ( sr2.starts_with ( string_view ()));
+ }
+
+void reverse ( const char *arg ) {
+// Round trip
+ string_view sr1 ( arg );
+ std::string string1 ( sr1.rbegin (), sr1.rend ());
+ string_view sr2 ( string1 );
+ std::string string2 ( sr2.rbegin (), sr2.rend ());
+
+ BOOST_TEST ( std::equal ( sr2.rbegin (), sr2.rend (), arg ));
+ BOOST_TEST ( string2 == arg );
+ BOOST_TEST ( std::equal ( sr1.begin (), sr1.end (), string2.begin ()));
+ }
+
+// This helper function eliminates signed vs. unsigned warnings
+string_view::size_type ptr_diff ( const char *res, const char *base ) {
+ BOOST_TEST ( res >= base );
+ return static_cast<string_view::size_type> ( res - base );
+ }
+
+void find ( const char *arg ) {
+ string_view sr1;
+ string_view sr2;
+ const char *p;
+
+// When we search for the empty string, we find it at position 0
+ BOOST_TEST ( sr1.find (sr2) == 0 );
+ BOOST_TEST ( sr1.rfind(sr2) == 0 );
+
+// Look for each character in the string(searching from the start)
+ p = arg;
+ sr1 = arg;
+ while ( *p ) {
+ string_view::size_type pos = sr1.find(*p);
+ BOOST_TEST ( pos != string_view::npos && ( pos <= ptr_diff ( p, arg )));
+ ++p;
+ }
+
+// Look for each character in the string (searching from the end)
+ p = arg;
+ sr1 = arg;
+ while ( *p ) {
+ string_view::size_type pos = sr1.rfind(*p);
+ BOOST_TEST ( pos != string_view::npos && pos < sr1.size () && ( pos >= ptr_diff ( p, arg )));
+ ++p;
+ }
+
+// Look for pairs on characters (searching from the start)
+ sr1 = arg;
+ p = arg;
+ while ( *p && *(p+1)) {
+ string_view sr3 ( p, 2 );
+ string_view::size_type pos = sr1.find ( sr3 );
+ BOOST_TEST ( pos != string_view::npos && pos <= static_cast<string_view::size_type>( p - arg ));
+ p++;
+ }
+
+ sr1 = arg;
+ p = arg;
+// for all possible chars, see if we find them in the right place.
+// Note that strchr will/might do the _wrong_ thing if we search for NULL
+ for ( int ch = 1; ch < 256; ++ch ) {
+ string_view::size_type pos = sr1.find(ch);
+ const char *strp = std::strchr ( arg, ch );
+ BOOST_TEST (( strp == NULL ) == ( pos == string_view::npos ));
+ if ( strp != NULL )
+ BOOST_TEST ( ptr_diff ( strp, arg ) == pos );
+ }
+
+ sr1 = arg;
+ p = arg;
+// for all possible chars, see if we find them in the right place.
+// Note that strchr will/might do the _wrong_ thing if we search for NULL
+ for ( int ch = 1; ch < 256; ++ch ) {
+ string_view::size_type pos = sr1.rfind(ch);
+ const char *strp = std::strrchr ( arg, ch );
+ BOOST_TEST (( strp == NULL ) == ( pos == string_view::npos ));
+ if ( strp != NULL )
+ BOOST_TEST ( ptr_diff ( strp, arg ) == pos );
+ }
+
+
+// Find everything at the start
+ p = arg;
+ sr1 = arg;
+ while ( !sr1.empty ()) {
+ string_view::size_type pos = sr1.find(*p);
+ BOOST_TEST ( pos == 0 );
+ sr1.remove_prefix (1);
+ ++p;
+ }
+
+// Find everything at the end
+ sr1 = arg;
+ p = arg + std::strlen ( arg ) - 1;
+ while ( !sr1.empty ()) {
+ string_view::size_type pos = sr1.rfind(*p);
+ BOOST_TEST ( pos == sr1.size () - 1 );
+ sr1.remove_suffix (1);
+ --p;
+ }
+
+// Find everything at the start
+ sr1 = arg;
+ p = arg;
+ while ( !sr1.empty ()) {
+ string_view::size_type pos = sr1.find_first_of(*p);
+ BOOST_TEST ( pos == 0 );
+ sr1.remove_prefix (1);
+ ++p;
+ }
+
+
+// Find everything at the end
+ sr1 = arg;
+ p = arg + std::strlen ( arg ) - 1;
+ while ( !sr1.empty ()) {
+ string_view::size_type pos = sr1.find_last_of(*p);
+ BOOST_TEST ( pos == sr1.size () - 1 );
+ sr1.remove_suffix (1);
+ --p;
+ }
+
+// Basic sanity checking for "find_first_of / find_first_not_of"
+ sr1 = arg;
+ sr2 = arg;
+ while ( !sr1.empty() ) {
+ BOOST_TEST ( sr1.find_first_of ( sr2 ) == 0 );
+ BOOST_TEST ( sr1.find_first_not_of ( sr2 ) == string_view::npos );
+ sr1.remove_prefix ( 1 );
+ }
+
+ p = arg;
+ sr1 = arg;
+ while ( *p ) {
+ string_view::size_type pos1 = sr1.find_first_of(*p);
+ string_view::size_type pos2 = sr1.find_first_not_of(*p);
+ BOOST_TEST ( pos1 != string_view::npos && pos1 < sr1.size () && pos1 <= ptr_diff ( p, arg ));
+ if ( pos2 != string_view::npos ) {
+ for ( size_t i = 0 ; i < pos2; ++i )
+ BOOST_TEST ( sr1[i] == *p );
+ BOOST_TEST ( sr1 [ pos2 ] != *p );
+ }
+
+ BOOST_TEST ( pos2 != pos1 );
+ ++p;
+ }
+
+// Basic sanity checking for "find_last_of / find_last_not_of"
+ sr1 = arg;
+ sr2 = arg;
+ while ( !sr1.empty() ) {
+ BOOST_TEST ( sr1.find_last_of ( sr2 ) == ( sr1.size () - 1 ));
+ BOOST_TEST ( sr1.find_last_not_of ( sr2 ) == string_view::npos );
+ sr1.remove_suffix ( 1 );
+ }
+
+ p = arg;
+ sr1 = arg;
+ while ( *p ) {
+ string_view::size_type pos1 = sr1.find_last_of(*p);
+ string_view::size_type pos2 = sr1.find_last_not_of(*p);
+ BOOST_TEST ( pos1 != string_view::npos && pos1 < sr1.size () && pos1 >= ptr_diff ( p, arg ));
+ BOOST_TEST ( pos2 == string_view::npos || pos1 < sr1.size ());
+ if ( pos2 != string_view::npos ) {
+ for ( size_t i = sr1.size () -1 ; i > pos2; --i )
+ BOOST_TEST ( sr1[i] == *p );
+ BOOST_TEST ( sr1 [ pos2 ] != *p );
+ }
+
+ BOOST_TEST ( pos2 != pos1 );
+ ++p;
+ }
+
+ }
+
+template <typename T>
+class custom_allocator {
+public:
+ typedef T value_type;
+ typedef T* pointer;
+ typedef const T* const_pointer;
+ typedef void* void_pointer;
+ typedef const void* const_void_pointer;
+ typedef std::size_t size_type;
+ typedef std::ptrdiff_t difference_type;
+ typedef T& reference;
+ typedef const T& const_reference;
+
+ template<class U>
+ struct rebind {
+ typedef custom_allocator<U> other;
+ };
+
+ custom_allocator() BOOST_NOEXCEPT {}
+ template <typename U>
+ custom_allocator(custom_allocator<U> const&) BOOST_NOEXCEPT {}
+
+ pointer allocate(size_type n) const {
+ return static_cast<pointer>(std::malloc(sizeof(value_type) * n));
+ }
+ void deallocate(pointer p, size_type) const BOOST_NOEXCEPT {
+ std::free(p);
+ }
+
+ pointer address(reference value) const BOOST_NOEXCEPT {
+ return &value;
+ }
+
+ const_pointer address(const_reference value) const BOOST_NOEXCEPT {
+ return &value;
+ }
+
+ BOOST_CONSTEXPR size_type max_size() const BOOST_NOEXCEPT {
+ return (~(size_type)0u) / sizeof(value_type);
+ }
+
+#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
+ template <class U, class... Args>
+ void construct(U* ptr, Args&&... args) const {
+ ::new((void*)ptr) U(static_cast<Args&&>(args)...);
+ }
+#else
+ template <class U, class V>
+ void construct(U* ptr, V&& value) const {
+ ::new((void*)ptr) U(static_cast<V&&>(value));
+ }
+#endif
+#else
+ template <class U, class V>
+ void construct(U* ptr, const V& value) const {
+ ::new((void*)ptr) U(value);
+ }
+#endif
+
+ template <class U>
+ void construct(U* ptr) const {
+ ::new((void*)ptr) U();
+ }
+
+ template <class U>
+ void destroy(U* ptr) const {
+ (void)ptr;
+ ptr->~U();
+ }
+ };
+
+template <typename T, typename U>
+BOOST_CONSTEXPR bool operator==(const custom_allocator<T> &, const custom_allocator<U> &) BOOST_NOEXCEPT {
+ return true;
+ }
+template <typename T, typename U>
+BOOST_CONSTEXPR bool operator!=(const custom_allocator<T> &, const custom_allocator<U> &) BOOST_NOEXCEPT {
+ return false;
+ }
+
+void to_string ( const char *arg ) {
+ string_view sr1;
+ std::string str1;
+ std::string str2;
+
+ str1.assign ( arg );
+ sr1 = arg;
+// str2 = sr1.to_string<std::allocator<char> > ();
+ str2 = sr1.to_string ();
+ BOOST_TEST ( str1 == str2 );
+
+ std::basic_string<char, std::char_traits<char>, custom_allocator<char> > str3 = sr1.to_string(custom_allocator<char>());
+ BOOST_TEST ( std::strcmp(str1.c_str(), str3.c_str()) == 0 );
+
+#ifndef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
+ std::string str4 = static_cast<std::string> ( sr1 );
+ BOOST_TEST ( str1 == str4 );
+#endif
+ }
+
+void compare ( const char *arg ) {
+ string_view sr1;
+ std::string str1;
+ std::string str2 = str1;
+
+ str1.assign ( arg );
+ sr1 = arg;
+ BOOST_TEST ( sr1 == sr1); // compare string_view and string_view
+ BOOST_TEST ( sr1 == str1); // compare string and string_view
+ BOOST_TEST ( str1 == sr1 ); // compare string_view and string
+ BOOST_TEST ( sr1 == arg ); // compare string_view and pointer
+ BOOST_TEST ( arg == sr1 ); // compare pointer and string_view
+
+ if ( sr1.size () > 0 ) {
+ (*str1.rbegin())++;
+ BOOST_TEST ( sr1 != str1 );
+ BOOST_TEST ( str1 != sr1 );
+ BOOST_TEST ( sr1 < str1 );
+ BOOST_TEST ( sr1 <= str1 );
+ BOOST_TEST ( str1 > sr1 );
+ BOOST_TEST ( str1 >= sr1 );
+
+ (*str1.rbegin()) -= 2;
+ BOOST_TEST ( sr1 != str1 );
+ BOOST_TEST ( str1 != sr1 );
+ BOOST_TEST ( sr1 > str1 );
+ BOOST_TEST ( sr1 >= str1 );
+ BOOST_TEST ( str1 < sr1 );
+ BOOST_TEST ( str1 <= sr1 );
+ }
+ }
+
+const char *test_strings [] = {
+ "",
+ "0",
+ "abc",
+ "AAA", // all the same
+ "adsfadadiaef;alkdg;aljt;j agl;sjrl;tjs;lga;lretj;srg[w349u5209dsfadfasdfasdfadsf",
+ "abc\0asdfadsfasf",
+ NULL
+ };
+
+int main()
+{
+ const char **p = &test_strings[0];
+
+ while ( *p != NULL ) {
+ starts_with ( *p );
+ ends_with ( *p );
+ reverse ( *p );
+ find ( *p );
+ to_string ( *p );
+ compare ( *p );
+
+ p++;
+ }
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/utility/test/string_view_test_io.cpp b/src/boost/libs/utility/test/string_view_test_io.cpp
new file mode 100644
index 000000000..416ff3383
--- /dev/null
+++ b/src/boost/libs/utility/test/string_view_test_io.cpp
@@ -0,0 +1,184 @@
+/*
+ * Copyright Andrey Semashev 2013.
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+/*!
+ * \file string_ref_test_io.cpp
+ * \author Andrey Semashev
+ * \date 26.05.2013
+ *
+ * \brief This header contains tests for stream operations of \c basic_string_ref.
+ */
+
+#include <boost/utility/string_view.hpp>
+
+#include <iomanip>
+#include <sstream>
+#include <algorithm>
+#include <iterator>
+#include <string>
+
+#include <boost/config.hpp>
+#include <boost/core/lightweight_test.hpp>
+
+/* Current implementations seem to be missing codecvt facets to convert chars to char16_t and char32_t even though the types are available.
+*/
+
+static const char* test_strings[] =
+{
+ "begin",
+ "abcd",
+ "end"
+};
+
+//! The context with test data for particular character type
+template< typename CharT >
+struct context
+{
+ typedef CharT char_type;
+ typedef std::basic_string< char_type > string_type;
+ typedef std::basic_ostringstream< char_type > ostream_type;
+
+ string_type begin, abcd, end;
+
+ context()
+ {
+ boost::string_view str = test_strings[0];
+ std::copy(str.begin(), str.end(), std::back_inserter(begin));
+
+ str = test_strings[1];
+ std::copy(str.begin(), str.end(), std::back_inserter(abcd));
+
+ str = test_strings[2];
+ std::copy(str.begin(), str.end(), std::back_inserter(end));
+ }
+};
+
+// Test regular output
+template<class CharT>
+void test_string_view_output()
+{
+ typedef CharT char_type;
+ typedef std::basic_ostringstream< char_type > ostream_type;
+ typedef boost::basic_string_view< char_type > string_view_type;
+
+ context< char_type > ctx;
+
+ ostream_type strm;
+ strm << string_view_type(ctx.abcd);
+ BOOST_TEST(strm.str() == ctx.abcd);
+}
+
+// Test support for padding
+template<class CharT>
+void test_padding()
+{
+ typedef CharT char_type;
+ typedef std::basic_ostringstream< char_type > ostream_type;
+ typedef boost::basic_string_view< char_type > string_view_type;
+
+ context< char_type > ctx;
+
+ // Test for padding
+ {
+ ostream_type strm_ref;
+ strm_ref << ctx.begin << std::setw(8) << string_view_type(ctx.abcd) << ctx.end;
+
+ ostream_type strm_correct;
+ strm_correct << ctx.begin << std::setw(8) << ctx.abcd << ctx.end;
+
+ BOOST_TEST(strm_ref.str() == strm_correct.str());
+ }
+
+ // Test for long padding
+ {
+ ostream_type strm_ref;
+ strm_ref << ctx.begin << std::setw(100) << string_view_type(ctx.abcd) << ctx.end;
+
+ ostream_type strm_correct;
+ strm_correct << ctx.begin << std::setw(100) << ctx.abcd << ctx.end;
+
+ BOOST_TEST(strm_ref.str() == strm_correct.str());
+ }
+
+ // Test that short width does not truncate the string
+ {
+ ostream_type strm_ref;
+ strm_ref << ctx.begin << std::setw(1) << string_view_type(ctx.abcd) << ctx.end;
+
+ ostream_type strm_correct;
+ strm_correct << ctx.begin << std::setw(1) << ctx.abcd << ctx.end;
+
+ BOOST_TEST(strm_ref.str() == strm_correct.str());
+ }
+}
+
+// Test support for padding fill
+template<class CharT>
+void test_padding_fill()
+{
+ typedef CharT char_type;
+ typedef std::basic_ostringstream< char_type > ostream_type;
+ typedef boost::basic_string_view< char_type > string_view_type;
+
+ context< char_type > ctx;
+
+ ostream_type strm_ref;
+ strm_ref << ctx.begin << std::setfill(static_cast< char_type >('x')) << std::setw(8) << string_view_type(ctx.abcd) << ctx.end;
+
+ ostream_type strm_correct;
+ strm_correct << ctx.begin << std::setfill(static_cast< char_type >('x')) << std::setw(8) << ctx.abcd << ctx.end;
+
+ BOOST_TEST(strm_ref.str() == strm_correct.str());
+}
+
+// Test support for alignment
+template<class CharT>
+void test_alignment()
+{
+ typedef CharT char_type;
+ typedef std::basic_ostringstream< char_type > ostream_type;
+ typedef boost::basic_string_view< char_type > string_view_type;
+
+ context< char_type > ctx;
+
+ // Left alignment
+ {
+ ostream_type strm_ref;
+ strm_ref << ctx.begin << std::left << std::setw(8) << string_view_type(ctx.abcd) << ctx.end;
+
+ ostream_type strm_correct;
+ strm_correct << ctx.begin << std::left << std::setw(8) << ctx.abcd << ctx.end;
+
+ BOOST_TEST(strm_ref.str() == strm_correct.str());
+ }
+
+ // Right alignment
+ {
+ ostream_type strm_ref;
+ strm_ref << ctx.begin << std::right << std::setw(8) << string_view_type(ctx.abcd) << ctx.end;
+
+ ostream_type strm_correct;
+ strm_correct << ctx.begin << std::right << std::setw(8) << ctx.abcd << ctx.end;
+
+ BOOST_TEST(strm_ref.str() == strm_correct.str());
+ }
+}
+
+template<class CharT>
+void test()
+{
+ test_string_view_output<CharT>();
+ test_padding<CharT>();
+ test_padding_fill<CharT>();
+ test_alignment<CharT>();
+}
+
+int main()
+{
+ test<char>();
+ test<wchar_t>();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/utility/test/value_init_test.cpp b/src/boost/libs/utility/test/value_init_test.cpp
new file mode 100644
index 000000000..ed7ec3d5b
--- /dev/null
+++ b/src/boost/libs/utility/test/value_init_test.cpp
@@ -0,0 +1,371 @@
+// Copyright 2002-2008, Fernando Luis Cacciola Carballal.
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// Test program for "boost/utility/value_init.hpp"
+//
+// 21 Ago 2002 (Created) Fernando Cacciola
+// 15 Jan 2008 (Added tests regarding compiler issues) Fernando Cacciola, Niels Dekker
+// 23 May 2008 (Added tests regarding initialized_value) Niels Dekker
+// 21 Ago 2008 (Added swap test) Niels Dekker
+
+#include <cstring> // For memcmp.
+#include <iostream>
+#include <string>
+
+#include "boost/utility/value_init.hpp"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#include <boost/core/lightweight_test.hpp>
+
+//
+// Sample POD type
+//
+struct POD
+{
+ POD () : f(0), c(0), i(0){}
+
+ POD ( char c_, int i_, float f_ ) : f(f_), c(c_), i(i_) {}
+
+ friend std::ostream& operator << ( std::ostream& os, POD const& pod )
+ { return os << '(' << pod.c << ',' << pod.i << ',' << pod.f << ')' ; }
+
+ friend bool operator == ( POD const& lhs, POD const& rhs )
+ { return lhs.f == rhs.f && lhs.c == rhs.c && lhs.i == rhs.i ; }
+
+ float f;
+ char c;
+ int i;
+} ;
+
+//
+// Sample non POD type
+//
+struct NonPODBase
+{
+ virtual ~NonPODBase() {}
+} ;
+struct NonPOD : NonPODBase
+{
+ NonPOD () : id() {}
+ explicit NonPOD ( std::string const& id_) : id(id_) {}
+
+ friend std::ostream& operator << ( std::ostream& os, NonPOD const& npod )
+ { return os << '(' << npod.id << ')' ; }
+
+ friend bool operator == ( NonPOD const& lhs, NonPOD const& rhs )
+ { return lhs.id == rhs.id ; }
+
+ std::string id ;
+} ;
+
+//
+// Sample aggregate POD struct type
+// Some compilers do not correctly value-initialize such a struct, for example:
+// Borland C++ Report #51854, "Value-initialization: POD struct should be zero-initialized "
+// http://qc.codegear.com/wc/qcmain.aspx?d=51854
+//
+struct AggregatePODStruct
+{
+ float f;
+ char c;
+ int i;
+};
+
+bool operator == ( AggregatePODStruct const& lhs, AggregatePODStruct const& rhs )
+{ return lhs.f == rhs.f && lhs.c == rhs.c && lhs.i == rhs.i ; }
+
+//
+// An aggregate struct that contains an std::string and an int.
+// Pavel Kuznetsov (MetaCommunications Engineering) used a struct like
+// this to reproduce the Microsoft Visual C++ compiler bug, reported as
+// Feedback ID 100744, "Value-initialization in new-expression"
+// https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=100744
+//
+struct StringAndInt
+{
+ std::string s;
+ int i;
+};
+
+bool operator == ( StringAndInt const& lhs, StringAndInt const& rhs )
+{ return lhs.s == rhs.s && lhs.i == rhs.i ; }
+
+
+//
+// A struct that has an explicit (user defined) destructor.
+// Some compilers do not correctly value-initialize such a struct, for example:
+// Microsoft Visual C++, Feedback ID 100744, "Value-initialization in new-expression"
+// https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=100744
+//
+struct StructWithDestructor
+{
+ int i;
+ ~StructWithDestructor() {}
+};
+
+bool operator == ( StructWithDestructor const& lhs, StructWithDestructor const& rhs )
+{ return lhs.i == rhs.i ; }
+
+
+//
+// A struct that has a virtual function.
+// Some compilers do not correctly value-initialize such a struct either, for example:
+// Microsoft Visual C++, Feedback ID 100744, "Value-initialization in new-expression"
+// https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=100744
+//
+struct StructWithVirtualFunction
+{
+ int i;
+ virtual void VirtualFunction();
+};
+
+void StructWithVirtualFunction::VirtualFunction()
+{
+}
+
+bool operator == ( StructWithVirtualFunction const& lhs, StructWithVirtualFunction const& rhs )
+{ return lhs.i == rhs.i ; }
+
+
+//
+// A struct that is derived from an aggregate POD struct.
+// Some compilers do not correctly value-initialize such a struct, for example:
+// GCC Bugzilla Bug 30111, "Value-initialization of POD base class doesn't initialize members",
+// reported by Jonathan Wakely, http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30111
+//
+struct DerivedFromAggregatePODStruct : AggregatePODStruct
+{
+ DerivedFromAggregatePODStruct() : AggregatePODStruct() {}
+};
+
+//
+// A struct that wraps an aggregate POD struct as data member.
+//
+struct AggregatePODStructWrapper
+{
+ AggregatePODStructWrapper() : dataMember() {}
+ AggregatePODStruct dataMember;
+};
+
+bool operator == ( AggregatePODStructWrapper const& lhs, AggregatePODStructWrapper const& rhs )
+{ return lhs.dataMember == rhs.dataMember ; }
+
+typedef unsigned char ArrayOfBytes[256];
+
+
+//
+// A struct that allows testing whether the appropriate copy functions are called.
+//
+struct CopyFunctionCallTester
+{
+ bool is_copy_constructed;
+ bool is_assignment_called;
+
+ CopyFunctionCallTester()
+ : is_copy_constructed(false), is_assignment_called(false) {}
+
+ CopyFunctionCallTester(const CopyFunctionCallTester & )
+ : is_copy_constructed(true), is_assignment_called(false) {}
+
+ CopyFunctionCallTester & operator=(const CopyFunctionCallTester & )
+ {
+ is_assignment_called = true ;
+ return *this ;
+ }
+};
+
+
+//
+// A struct that allows testing whether its customized swap function is called.
+//
+struct SwapFunctionCallTester
+{
+ bool is_custom_swap_called;
+ int data;
+
+ SwapFunctionCallTester()
+ : is_custom_swap_called(false), data(0) {}
+
+ SwapFunctionCallTester(const SwapFunctionCallTester & arg)
+ : is_custom_swap_called(false), data(arg.data) {}
+
+ void swap(SwapFunctionCallTester & arg)
+ {
+ std::swap(data, arg.data);
+ is_custom_swap_called = true;
+ arg.is_custom_swap_called = true;
+ }
+};
+
+void swap(SwapFunctionCallTester & lhs, SwapFunctionCallTester & rhs)
+{
+ lhs.swap(rhs);
+}
+
+
+
+template<class T>
+void check_initialized_value ( T const& y )
+{
+ T initializedValue = boost::initialized_value ;
+ BOOST_TEST ( y == initializedValue ) ;
+}
+
+#ifdef __BORLANDC__
+#if __BORLANDC__ == 0x582
+void check_initialized_value( NonPOD const& )
+{
+ // The initialized_value check is skipped for Borland 5.82
+ // and this type (NonPOD), because the following statement
+ // won't compile on this particular compiler version:
+ // NonPOD initializedValue = boost::initialized_value() ;
+ //
+ // This is caused by a compiler bug, that is fixed with a newer version
+ // of the Borland compiler. The Release Notes for Delphi(R) 2007 for
+ // Win32(R) and C++Builder(R) 2007 (http://dn.codegear.com/article/36575)
+ // say about similar statements:
+ // both of these statements now compile but under 5.82 got the error:
+ // Error E2015: Ambiguity between 'V::V(const A &)' and 'V::V(const V &)'
+}
+#endif
+#endif
+
+//
+// This test function tests boost::value_initialized<T> for a specific type T.
+// The first argument (y) is assumed have the value of a value-initialized object.
+// Returns true on success.
+//
+template<class T>
+bool test ( T const& y, T const& z )
+{
+ const int errors_before_test = boost::detail::test_errors();
+
+ check_initialized_value(y);
+
+ boost::value_initialized<T> x ;
+ BOOST_TEST ( y == x ) ;
+ BOOST_TEST ( y == boost::get(x) ) ;
+
+ static_cast<T&>(x) = z ;
+ boost::get(x) = z ;
+ BOOST_TEST ( x == z ) ;
+
+ boost::value_initialized<T> const x_c ;
+ BOOST_TEST ( y == x_c ) ;
+ BOOST_TEST ( y == boost::get(x_c) ) ;
+ T& x_c_ref = const_cast<T&>( boost::get(x_c) ) ;
+ x_c_ref = z ;
+ BOOST_TEST ( x_c == z ) ;
+
+ boost::value_initialized<T> const copy1 = x;
+ BOOST_TEST ( boost::get(copy1) == boost::get(x) ) ;
+
+ boost::value_initialized<T> copy2;
+ copy2 = x;
+ BOOST_TEST ( boost::get(copy2) == boost::get(x) ) ;
+
+ {
+ boost::value_initialized<T> * ptr = new boost::value_initialized<T>;
+ BOOST_TEST ( y == *ptr ) ;
+ delete ptr;
+ }
+
+#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
+ boost::value_initialized<T const> cx ;
+ BOOST_TEST ( y == cx ) ;
+ BOOST_TEST ( y == boost::get(cx) ) ;
+
+ boost::value_initialized<T const> const cx_c ;
+ BOOST_TEST ( y == cx_c ) ;
+ BOOST_TEST ( y == boost::get(cx_c) ) ;
+#endif
+
+ return boost::detail::test_errors() == errors_before_test ;
+}
+
+int main()
+{
+ BOOST_TEST ( test( 0,1234 ) ) ;
+ BOOST_TEST ( test( 0.0,12.34 ) ) ;
+ BOOST_TEST ( test( POD(0,0,0.0), POD('a',1234,56.78f) ) ) ;
+ BOOST_TEST ( test( NonPOD( std::string() ), NonPOD( std::string("something") ) ) ) ;
+
+ NonPOD NonPOD_object( std::string("NonPOD_object") );
+ BOOST_TEST ( test<NonPOD *>( 0, &NonPOD_object ) ) ;
+
+ AggregatePODStruct zeroInitializedAggregatePODStruct = { 0.0f, '\0', 0 };
+ AggregatePODStruct nonZeroInitializedAggregatePODStruct = { 1.25f, 'a', -1 };
+ BOOST_TEST ( test(zeroInitializedAggregatePODStruct, nonZeroInitializedAggregatePODStruct) );
+
+ StringAndInt stringAndInt0;
+ StringAndInt stringAndInt1;
+ stringAndInt0.i = 0;
+ stringAndInt1.i = 1;
+ stringAndInt1.s = std::string("1");
+ BOOST_TEST ( test(stringAndInt0, stringAndInt1) );
+
+ StructWithDestructor structWithDestructor0;
+ StructWithDestructor structWithDestructor1;
+ structWithDestructor0.i = 0;
+ structWithDestructor1.i = 1;
+ BOOST_TEST ( test(structWithDestructor0, structWithDestructor1) );
+
+ StructWithVirtualFunction structWithVirtualFunction0;
+ StructWithVirtualFunction structWithVirtualFunction1;
+ structWithVirtualFunction0.i = 0;
+ structWithVirtualFunction1.i = 1;
+ BOOST_TEST ( test(structWithVirtualFunction0, structWithVirtualFunction1) );
+
+ DerivedFromAggregatePODStruct derivedFromAggregatePODStruct0;
+ DerivedFromAggregatePODStruct derivedFromAggregatePODStruct1;
+ static_cast<AggregatePODStruct &>(derivedFromAggregatePODStruct0) = zeroInitializedAggregatePODStruct;
+ static_cast<AggregatePODStruct &>(derivedFromAggregatePODStruct1) = nonZeroInitializedAggregatePODStruct;
+ BOOST_TEST ( test(derivedFromAggregatePODStruct0, derivedFromAggregatePODStruct1) );
+
+ AggregatePODStructWrapper aggregatePODStructWrapper0;
+ AggregatePODStructWrapper aggregatePODStructWrapper1;
+ aggregatePODStructWrapper0.dataMember = zeroInitializedAggregatePODStruct;
+ aggregatePODStructWrapper1.dataMember = nonZeroInitializedAggregatePODStruct;
+ BOOST_TEST ( test(aggregatePODStructWrapper0, aggregatePODStructWrapper1) );
+
+ ArrayOfBytes zeroInitializedArrayOfBytes = { 0 };
+ boost::value_initialized<ArrayOfBytes> valueInitializedArrayOfBytes;
+ BOOST_TEST (std::memcmp(get(valueInitializedArrayOfBytes), zeroInitializedArrayOfBytes, sizeof(ArrayOfBytes)) == 0);
+
+ boost::value_initialized<ArrayOfBytes> valueInitializedArrayOfBytes2;
+ valueInitializedArrayOfBytes2 = valueInitializedArrayOfBytes;
+ BOOST_TEST (std::memcmp(get(valueInitializedArrayOfBytes), get(valueInitializedArrayOfBytes2), sizeof(ArrayOfBytes)) == 0);
+
+ boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester1;
+ BOOST_TEST ( ! get(copyFunctionCallTester1).is_copy_constructed);
+ BOOST_TEST ( ! get(copyFunctionCallTester1).is_assignment_called);
+
+ boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester2 = boost::value_initialized<CopyFunctionCallTester>(copyFunctionCallTester1);
+ BOOST_TEST ( get(copyFunctionCallTester2).is_copy_constructed);
+ BOOST_TEST ( ! get(copyFunctionCallTester2).is_assignment_called);
+
+ boost::value_initialized<CopyFunctionCallTester> copyFunctionCallTester3;
+ copyFunctionCallTester3 = boost::value_initialized<CopyFunctionCallTester>(copyFunctionCallTester1);
+ BOOST_TEST ( ! get(copyFunctionCallTester3).is_copy_constructed);
+ BOOST_TEST ( get(copyFunctionCallTester3).is_assignment_called);
+
+ boost::value_initialized<SwapFunctionCallTester> swapFunctionCallTester1;
+ boost::value_initialized<SwapFunctionCallTester> swapFunctionCallTester2;
+ get(swapFunctionCallTester1).data = 1;
+ get(swapFunctionCallTester2).data = 2;
+ boost::swap(swapFunctionCallTester1, swapFunctionCallTester2);
+ BOOST_TEST( get(swapFunctionCallTester1).data == 2 );
+ BOOST_TEST( get(swapFunctionCallTester2).data == 1 );
+ BOOST_TEST( get(swapFunctionCallTester1).is_custom_swap_called );
+ BOOST_TEST( get(swapFunctionCallTester2).is_custom_swap_called );
+
+ return boost::report_errors();
+}
+
+
diff --git a/src/boost/libs/utility/test/value_init_test_fail1.cpp b/src/boost/libs/utility/test/value_init_test_fail1.cpp
new file mode 100644
index 000000000..789e6b334
--- /dev/null
+++ b/src/boost/libs/utility/test/value_init_test_fail1.cpp
@@ -0,0 +1,27 @@
+// Copyright 2002, Fernando Luis Cacciola Carballal.
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// Test program for "boost/utility/value_init.hpp"
+//
+// Initial: 21 Agu 2002
+
+#include <iostream>
+#include <string>
+
+#include "boost/utility/value_init.hpp"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+int main()
+{
+ boost::value_initialized<int> const x_c ;
+
+ get(x_c) = 1234 ; // this should produce an ERROR
+
+ return 0;
+}
diff --git a/src/boost/libs/utility/test/value_init_test_fail2.cpp b/src/boost/libs/utility/test/value_init_test_fail2.cpp
new file mode 100644
index 000000000..052a2bdff
--- /dev/null
+++ b/src/boost/libs/utility/test/value_init_test_fail2.cpp
@@ -0,0 +1,27 @@
+// Copyright 2002, Fernando Luis Cacciola Carballal.
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// Test program for "boost/utility/value_init.hpp"
+//
+// Initial: 21 Agu 2002
+
+#include <iostream>
+#include <string>
+
+#include "boost/utility/value_init.hpp"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+int main()
+{
+ boost::value_initialized<int const> cx ;
+
+ get(cx) = 1234 ; // this should produce an ERROR
+
+ return 0;
+}
diff --git a/src/boost/libs/utility/test/value_init_test_fail3.cpp b/src/boost/libs/utility/test/value_init_test_fail3.cpp
new file mode 100644
index 000000000..1801f827a
--- /dev/null
+++ b/src/boost/libs/utility/test/value_init_test_fail3.cpp
@@ -0,0 +1,27 @@
+// Copyright 2002, Fernando Luis Cacciola Carballal.
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// Test program for "boost/utility/value_init.hpp"
+//
+// Initial: 21 Agu 2002
+
+#include <iostream>
+#include <string>
+
+#include "boost/utility/value_init.hpp"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+int main()
+{
+ boost::value_initialized<int const> const cx_c ;
+
+ get(cx_c) = 1234 ; // this should produce an ERROR
+
+ return 0;
+}
diff --git a/src/boost/libs/utility/test/value_init_workaround_test.cpp b/src/boost/libs/utility/test/value_init_workaround_test.cpp
new file mode 100644
index 000000000..9ffdffc5d
--- /dev/null
+++ b/src/boost/libs/utility/test/value_init_workaround_test.cpp
@@ -0,0 +1,163 @@
+// Copyright 2010, Niels Dekker.
+//
+// Distributed under the Boost Software License, Version 1.0. (See
+// accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// Test program for the boost::value_initialized<T> workaround.
+//
+// 17 June 2010 (Created) Niels Dekker
+
+// Switch the workaround off, before inluding "value_init.hpp".
+#define BOOST_DETAIL_VALUE_INIT_WORKAROUND 0
+#include <boost/utility/value_init.hpp>
+
+#include <iostream> // For cout.
+#include <cstdlib> // For EXIT_SUCCESS and EXIT_FAILURE.
+
+namespace
+{
+ struct empty_struct
+ {
+ };
+
+ // A POD aggregate struct derived from an empty struct.
+ // Similar to struct Foo1 from Microsoft Visual C++ bug report 484295,
+ // "VC++ does not value-initialize members of derived classes without
+ // user-declared constructor", reported in 2009 by Sylvester Hesp:
+ // https://connect.microsoft.com/VisualStudio/feedback/details/484295
+ struct derived_struct: empty_struct
+ {
+ int data;
+ };
+
+ bool is_value_initialized(const derived_struct& arg)
+ {
+ return arg.data == 0;
+ }
+
+
+ class virtual_destructor_holder
+ {
+ public:
+ int i;
+ virtual ~virtual_destructor_holder()
+ {
+ }
+ };
+
+ bool is_value_initialized(const virtual_destructor_holder& arg)
+ {
+ return arg.i == 0;
+ }
+
+ // Equivalent to the Stats class from GCC Bug 33916,
+ // "Default constructor fails to initialize array members", reported in 2007 by
+ // Michael Elizabeth Chastain: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33916
+ // and fixed for GCC 4.2.4.
+ class private_int_array_pair
+ {
+ friend bool is_value_initialized(const private_int_array_pair& arg);
+ private:
+ int first[12];
+ int second[12];
+ };
+
+ bool is_value_initialized(const private_int_array_pair& arg)
+ {
+ for ( unsigned i = 0; i < 12; ++i)
+ {
+ if ( (arg.first[i] != 0) || (arg.second[i] != 0) )
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ struct int_pair_struct
+ {
+ int first;
+ int second;
+ };
+
+ typedef int int_pair_struct::*ptr_to_member_type;
+
+ struct ptr_to_member_struct
+ {
+ ptr_to_member_type data;
+ };
+
+ bool is_value_initialized(const ptr_to_member_struct& arg)
+ {
+ return arg.data == 0;
+ }
+
+ template <typename T>
+ bool is_value_initialized(const T(& arg)[2])
+ {
+ return
+ is_value_initialized(arg[0]) &&
+ is_value_initialized(arg[1]);
+ }
+
+ template <typename T>
+ bool is_value_initialized(const boost::value_initialized<T>& arg)
+ {
+ return is_value_initialized(arg.data());
+ }
+
+ // Returns zero when the specified object is value-initializated, and one otherwise.
+ // Prints a message to standard output if the value-initialization has failed.
+ template <class T>
+ unsigned failed_to_value_initialized(const T& object, const char *const object_name)
+ {
+ if ( is_value_initialized(object) )
+ {
+ return 0u;
+ }
+ else
+ {
+ std::cout << "Note: Failed to value-initialize " << object_name << '.' << std::endl;
+ return 1u;
+ }
+ }
+
+// A macro that passed both the name and the value of the specified object to
+// the function above here.
+#define FAILED_TO_VALUE_INITIALIZE(value) failed_to_value_initialized(value, #value)
+
+ // Equivalent to the dirty_stack() function from GCC Bug 33916,
+ // "Default constructor fails to initialize array members", reported in 2007 by
+ // Michael Elizabeth Chastain: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33916
+ void dirty_stack()
+ {
+ unsigned char array_on_stack[4096];
+ for (unsigned i = 0; i < sizeof(array_on_stack); ++i)
+ {
+ array_on_stack[i] = 0x11;
+ }
+ }
+
+}
+
+
+int main()
+{
+ dirty_stack();
+
+ // TODO More types may be added later.
+ const unsigned num_failures =
+ FAILED_TO_VALUE_INITIALIZE(boost::value_initialized<derived_struct>()) +
+ FAILED_TO_VALUE_INITIALIZE(boost::value_initialized<virtual_destructor_holder[2]>()) +
+ FAILED_TO_VALUE_INITIALIZE(boost::value_initialized<private_int_array_pair>()) +
+ FAILED_TO_VALUE_INITIALIZE(boost::value_initialized<ptr_to_member_struct>());
+
+#ifdef BOOST_DETAIL_VALUE_INIT_WORKAROUND_SUGGESTED
+ // One or more failures are expected.
+ return num_failures > 0 ? EXIT_SUCCESS : EXIT_FAILURE;
+#else
+ // No failures are expected.
+ return num_failures == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
+#endif
+}
diff --git a/src/boost/libs/utility/throw_exception.html b/src/boost/libs/utility/throw_exception.html
new file mode 100644
index 000000000..141f48759
--- /dev/null
+++ b/src/boost/libs/utility/throw_exception.html
@@ -0,0 +1,15 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<meta http-equiv=refresh content="0; URL=../exception/doc/throw_exception.html">
+<title>Automatic redirection</title>
+</head>
+<body>
+Automatic redirection failed, please go to
+<a href="../exception/doc/throw_exception.html">throw_exception.html</a>.&nbsp;<hr>
+<p>© Copyright Beman Dawes, 2001</p>
+<p>Distributed under the Boost Software License, Version 1.0. (See accompanying
+file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy
+at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</p>
+</body>
+</html>
diff --git a/src/boost/libs/utility/utility.htm b/src/boost/libs/utility/utility.htm
new file mode 100644
index 000000000..711b58c26
--- /dev/null
+++ b/src/boost/libs/utility/utility.htm
@@ -0,0 +1,583 @@
+<html>
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <title>Header boost/utility.hpp Documentation</title>
+ </head>
+ <body bgcolor="#FFFFFF" text="#000000">
+ <h1><img src="../../boost.png" alt="boost.png (6897 bytes)" align="center" WIDTH="277" HEIGHT="86">Header
+ <a href="../../boost/utility.hpp">boost/utility.hpp</a></h1>
+ <p>The entire contents of the header <code><a href="../../boost/utility.hpp">&lt;boost/utility.hpp&gt;</a></code>
+ are in <code>namespace boost</code>.</p>
+ <h2>Contents</h2>
+ <ul>
+ <li>
+ Class templates supporting the <a href="doc/html/base_from_member.html">
+ base-from-member idiom</a></li>
+ <li>
+ Function templates <a href="../core/doc/html/core/checked_delete.html">checked_delete() and
+ checked_array_delete()</a> (moved to the Boost.Core library)</li>
+ <li>
+ Function templates <a href="../iterator/doc/html/iterator/algorithms/next_prior.html">next() and prior()</a> (moved to the Boost.Iterator library)</li>
+ <li>
+ Class <a href="../core/doc/html/core/noncopyable.html">noncopyable</a> (moved to the Boost.Core library)</li>
+ <li>
+ Function template <a href="../core/doc/html/core/addressof.html">addressof()</a> (moved to the Boost.Core library)</li>
+ <li>Class template <a href="#result_of">result_of</a></li>
+ <li>
+ Macro <a href="#BOOST_BINARY">BOOST_BINARY</a></li>
+ <li><a href="index.html">Other utilities not part of <code>utility.hpp</code></a></li>
+ </ul>
+ <h2>
+
+ <h2><a name="result_of">Class template
+ result_of</a></h2> <p>The class template
+ <code>result_of</code> helps determine the type of a
+ call expression. For example, given an lvalue <code>f</code> of
+ type <code>F</code> and lvalues <code>t1</code>,
+ <code>t2</code>, ..., <code>t<em>N</em></code> of
+ types <code>T1</code>, <code>T2</code>, ...,
+ <code>T<em>N</em></code>, respectively, the type
+ <code>result_of&lt;F(T1, T2, ...,
+ T<em>N</em>)&gt;::type</code> defines the result type
+ of the expression <code>f(t1, t2,
+ ...,t<em>N</em>)</code>. This implementation permits
+ the type <code>F</code> to be a function pointer,
+ function reference, member function pointer, or class
+ type. By default, <em>N</em> may be any value between 0 and
+ 16. To change the upper limit, define the macro
+ <code>BOOST_RESULT_OF_NUM_ARGS</code> to the maximum
+ value for <em>N</em>. Class template <code>result_of</code>
+ resides in the header <code>&lt;<a
+ href="../../boost/utility/result_of.hpp">boost/utility/result_of.hpp</a>&gt;</code>.</p>
+
+ <p>If your compiler's support for <code>decltype</code> is
+ adequate, <code>result_of</code> automatically uses it to
+ deduce the type of the call expression, in which case
+ <code>result_of&lt;F(T1, T2, ...,
+ T<em>N</em>)&gt;::type</code> names the type
+ <code>decltype(boost::declval&lt;F&gt;()(boost::declval&lt;T1&gt;(),
+ boost::declval&lt;T2&gt;(), ...,
+ boost::declval&lt;T<em>N</em>&gt;()))</code>, as in the
+ following example.</p>
+
+ <blockquote>
+ <pre>struct functor {
+ template&lt;class T&gt;
+ T operator()(T x)
+ {
+ return x;
+ }
+};
+
+typedef boost::result_of&lt;
+ functor(int)
+&gt;::type type; // type is int</pre>
+ </blockquote>
+
+ <p>You can test whether <code>result_of</code> is using
+ <code>decltype</code> by checking if the macro
+ <code>BOOST_RESULT_OF_USE_DECLTYPE</code> is defined after
+ including <code>result_of.hpp</code>. You can also force
+ <code>result_of</code> to use <code>decltype</code> by
+ defining <code>BOOST_RESULT_OF_USE_DECLTYPE</code> prior
+ to including <code>result_of.hpp</code>.</p>
+
+ <p>If <code>decltype</code> is not used,
+ then automatic result type deduction of function
+ objects is not possible. Instead, <code>result_of</code>
+ uses the following protocol to allow the programmer to
+ specify a type. When <code>F</code> is a class type with a
+ member type <code>result_type</code>,
+ <code>result_of&lt;F(T1, T2, ...,
+ T<em>N</em>)&gt;::type</code> is
+ <code>F::result_type</code>. When <code>F</code> does
+ not contain <code>result_type</code>,
+ <code>result_of&lt;F(T1, T2, ...,
+ T<em>N</em>)&gt;::type</code> is <code>F::result&lt;F(T1,
+ T2, ..., T<em>N</em>)&gt;::type</code> when
+ <code><em>N</em> &gt; 0</code> or <code>void</code>
+ when <code><em>N</em> = 0</code>. Note that it is the
+ responsibility of the programmer to ensure that
+ function objects accurately advertise their result
+ type via this protocol, as in the following
+ example.</p>
+
+ <blockquote>
+ <pre>struct functor {
+ template&lt;class&gt; struct result;
+
+ template&lt;class F, class T&gt;
+ struct result&lt;F(T)&gt; {
+ typedef T type;
+ };
+
+ template&lt;class T&gt;
+ T operator()(T x)
+ {
+ return x;
+ }
+};
+
+typedef boost::result_of&lt;
+ functor(int)
+&gt;::type type; // type is int</pre>
+ </blockquote>
+
+ <p>Since <code>decltype</code> is a new language
+ feature recently standardized in C++11,
+ if you are writing a function object
+ to be used with <code>result_of</code>, for
+ maximum portability, you might consider following
+ the above protocol even if your compiler has
+ proper <code>decltype</code> support. If you wish to continue to
+ use the protocol on compilers that
+ support <code>decltype</code>, there are two options:
+ You can use <code>boost::tr1_result_of</code>, which is also
+ defined in <code>&lt;<a href="../../boost/utility/result_of.hpp">boost/utility/result_of.hpp</a>&gt;</code>.
+ Alternatively, you can define the macro
+ <code>BOOST_RESULT_OF_USE_TR1</code>, which causes
+ <code>result_of</code> to use the protocol described
+ above instead of <code>decltype</code>. If you choose to
+ follow the protocol, take care to ensure that the
+ <code>result_type</code> and
+ <code>result&lt;&gt;</code> members accurately
+ represent the return type of
+ <code>operator()</code> given a call expression.</p>
+
+ <p>Additionally, <code>boost::result_of</code>
+ provides a third mode of operation, which some users
+ may find convenient. When
+ <code>BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK</code>
+ is defined, <code>boost::result_of</code> behaves as
+ follows. If the function object has a member
+ type <code>result_type</code> or member
+ template <code>result&lt;&gt;</code>, then
+ <code>boost::result_of</code> will use the TR1
+ protocol. Otherwise,
+ <code>boost::result_of</code> will
+ use <code>decltype</code>. Using TR1 with
+ a <code>declytpe</code> fallback may workaround
+ certain problems at the cost of portability. For
+ example:
+ <ul>
+ <li>Deficient compiler: If your code
+ requires <code>boost::result_of</code> to work
+ with incomplete return types but your
+ compiler's <code>decltype</code> implementation
+ does not support incomplete return types, then you
+ can use the TR1 protocol as a workaround. Support
+ for incomplete return types was added late in the
+ C++11 standardization process
+ (see <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3276.pdf">N3276</a>)
+ and is not implemented by some compilers.</li>
+
+ <li>Deficient legacy code: If your existing TR1
+ function object advertises a different type than
+ the actual result type deduced
+ by <code>decltype</code>, then using TR1 with a
+ <code>decltype</code> fallback will allow you to
+ work with both your existing TR1 function objects
+ and new C++11 function object. This situation
+ could occur if your legacy function objects
+ misused the TR1 protocol. See the documentation on
+ known <a href="#result_of_tr1_diff">differences</a>
+ between <code>boost::result_of</code> and TR1.</li>
+ </ul>
+
+ <a name="BOOST_NO_RESULT_OF"></a>
+ <p>This implementation of <code>result_of</code>
+ requires class template partial specialization, the
+ ability to parse function types properly, and support
+ for SFINAE. If <code>result_of</code> is not supported
+ by your compiler, including the header
+ <code>boost/utility/result_of.hpp</code> will
+ define the macro <code>BOOST_NO_RESULT_OF</code>.</p>
+
+ <p>For additional information
+ about <code>result_of</code>, see the C++ Library
+ Technical Report,
+ <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1836.pdf">N1836</a>,
+ or, for motivation and design rationale,
+ the <code>result_of</code> <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1454.html">proposal</a>.</p>
+
+ <a name="result_of_guidelines">
+ <h3>Usage guidelines for boost::result_of</h3>
+ </a>
+
+ <p>The following are general suggestions about when
+ and how to use <code>boost::result_of</code>.</p>
+
+ <ol>
+ <li> If you are targeting C++11 and are not concerned
+ about portability to non-compliant compilers or
+ previous versions of the standard, then use
+ <code>std::result_of</code>. If <code>std::result_of</code>
+ meets your needs, then there's no reason to stop using
+ it.</li>
+
+ <li> If you are targeting C++11 but may port your code
+ to legacy compilers at some time in the future, then
+ use <code>boost::result_of</code> with
+ <code>decltype</code>. When <code>decltype</code> is
+ used <code>boost::result_of</code>
+ and <code>std::result_of</code> are usually
+ interchangeable. See the documentation on
+ known <a href="#result_of_cxx11_diff">differences</a>
+ between boost::result_of and C++11 result_of.</li>
+
+ <li> If compiler portability is required,
+ use <code>boost::result_of</code> with the TR1 protocol.</li>
+ </ol>
+
+ <p>Regardless of how you
+ configure <code>boost::result_of</code>, it is
+ important to bear in mind that the return type of a
+ function may change depending on its arguments, and
+ additionally, the return type of a member function may
+ change depending on the cv-qualification of the
+ object. <code>boost::result_of</code> must be passed
+ the appropriately cv-qualified types in order to
+ deduce the corresponding return type. For example:
+
+ <blockquote>
+ <pre>struct functor {
+ int& operator()(int);
+ int const& operator()(int) const;
+
+ float& operator()(float&);
+ float const& operator()(float const&);
+};
+
+typedef boost::result_of&lt;
+ functor(int)
+&gt;::type type1; // type1 is int &
+
+typedef boost::result_of&lt;
+ const functor(int)
+&gt;::type type2; // type2 is int const &
+
+typedef boost::result_of&lt;
+ functor(float&)
+&gt;::type type3; // type3 is float &
+
+typedef boost::result_of&lt;
+ functor(float const&)
+&gt;::type type4; // type4 is float const &</pre>
+ </blockquote>
+
+ <a name="result_of_tr1_protocol_guidelines">
+ <h3>Usage guidelines for the TR1 result_of protocol</h3>
+ </a>
+
+ <p>On compliant C++11
+ compilers, <code>boost::result_of</code> can
+ use <code>decltype</code> to deduce the type of any
+ call expression, including calls to function
+ objects. However, on pre-C++11 compilers or on
+ compilers without adequate decltype support,
+ additional scaffolding is needed from function
+ objects as described above. The following are
+ suggestions about how to use the TR1 protocol.</p>
+
+ <ul>
+ <li>When the return type does not depend on the
+ argument types or the cv-qualification of the
+ function object, simply
+ define <code>result_type</code>. There is no need
+ to use the <code>result</code> template unless the
+ return type varies.</li>
+
+ <li>Use the protocol specified type when defining
+ function prototypes. This can help ensure the
+ actual return type does not get out of sync with
+ the protocol specification. For example:
+
+ <blockquote>
+ <pre>struct functor {
+ typedef int result_type;
+ result_type operator()(int);
+};</pre>
+ </blockquote> </li>
+
+ <li>Always specify the <code>result</code>
+ specialization near the corresponding
+ <code>operator()</code> overload. This can make it
+ easier to keep the specializations in sync with the
+ overloads. For example:
+
+ <blockquote>
+ <pre>struct functor {
+ template&lt;class&gt; struct result;
+
+ template&lt;class F&gt;
+ struct result&lt;F(int)&gt; {
+ typedef int& type;
+ };
+ result&lt;functor(int)&gt;::type operator()(int);
+
+ template&lt;class F&gt;
+ struct result&lt;const F(int)&gt; {
+ typedef int const& type;
+ };
+ result&lt;const functor(int)&gt;::type operator()(int) const;
+};</pre>
+ </blockquote> </li>
+
+ <li>Use type transformations to simplify
+ the <code>result</code> template specialization. For
+ example, the following uses
+ <a href="../type_traits/doc/html/index.html">Boost.TypeTraits</a>
+ to specialize the <code>result</code> template for
+ a single <code>operator()</code> that can be called on
+ both a const and non-const function object with
+ either an lvalue or rvalue argument.
+
+ <blockquote>
+ <pre>struct functor {
+ template&lt;class&gt; struct result;
+
+ template&lt;class F, class T&gt;
+ struct result&lt;F(T)&gt;
+ : boost::remove_cv&lt;
+ typename boost::remove_reference&lt;T&gt;::type
+ &gt;
+ {};
+
+ template&lt;class T&gt;
+ T operator()(T const&amp; x) const;
+};</pre>
+ </blockquote></li>
+ </ul>
+
+ <a name="result_of_tr1_diff">
+ <h3>Known differences between boost::result_of and TR1 result_of</h3>
+ </a>
+
+ When using <code>decltype</code>, <code>boost::result_of</code>
+ ignores the TR1 protocol and instead deduces the
+ return type of function objects directly
+ via <code>decltype</code>. In most situations, users
+ will not notice a difference, so long as they use the
+ protocol correctly. The following are situations in
+ which the type deduced
+ by <code>boost::result_of</code> is known to differ depending on
+ whether <code>decltype</code> or the TR1 protocol is
+ used.
+
+ <ul>
+ <li> TR1 protocol misusage
+
+ <p>When using the TR1
+ protocol, <code>boost::result_of</code> cannot
+ detect whether the actual type of a call to a
+ function object is the same as the type specified
+ by the protocol, which allows for the possibility
+ of inadvertent mismatches between the specified
+ type and the actual type. When
+ using <code>decltype</code>, these subtle bugs
+ may result in compilation errors. For example:</p>
+
+ <blockquote>
+ <pre>struct functor {
+ typedef short result_type;
+ int operator()(short);
+};
+
+#ifdef BOOST_RESULT_OF_USE_DECLTYPE
+
+BOOST_STATIC_ASSERT((
+ boost::is_same&lt;boost::result_of&lt;functor(short)&gt;::type, int&gt;::value
+));
+
+#else
+
+BOOST_STATIC_ASSERT((
+ boost::is_same&lt;boost::result_of&lt;functor(short)&gt;::type, short&gt;::value
+));
+
+#endif</pre>
+ </blockquote>
+
+ <p>Note that the user can
+ force <code>boost::result_of</code> to use the TR1
+ protocol even on platforms that
+ support <code>decltype</code> by
+ defining <code>BOOST_RESULT_OF_USE_TR1</code>.</p></li>
+
+ <li> Nullary function objects
+
+ <p>When using the TR1 protocol, <code>boost::result_of</code>
+ cannot always deduce the type of calls to
+ nullary function objects, in which case the
+ type defaults to void. When using <code>decltype</code>,
+ <code>boost::result_of</code> always gives the actual type of the
+ call expression. For example:</p>
+
+ <blockquote>
+ <pre>struct functor {
+ template&lt;class&gt; struct result {
+ typedef int type;
+ };
+ int operator()();
+};
+
+#ifdef BOOST_RESULT_OF_USE_DECLTYPE
+
+BOOST_STATIC_ASSERT((
+ boost::is_same&lt;boost::result_of&lt;functor()&gt;::type, int&gt;::value
+));
+
+#else
+
+BOOST_STATIC_ASSERT((
+ boost::is_same&lt;boost::result_of&lt;functor()&gt;::type, void&gt;::value
+));
+
+#endif</pre>
+ </blockquote>
+
+ <p>Note that there are some workarounds for the
+ nullary function problem. So long as the return
+ type does not vary,
+ <code>result_type</code> can always be used to
+ specify the return type regardless of arity. If the
+ return type does vary, then the user can
+ specialize <code>boost::result_of</code> itself for
+ nullary calls.</p></li>
+
+ <li> Non-class prvalues and cv-qualification
+
+ <p>When using the TR1
+ protocol, <code>boost::result_of</code> will
+ report the cv-qualified type specified
+ by <code>result_type</code> or
+ the <code>result</code> template regardless of
+ the actual cv-qualification of the call
+ expression. When using
+ <code>decltype</code>, <code>boost::result_of</code>
+ will report the actual type of the call expression,
+ which is not cv-qualified when the expression is a
+ non-class prvalue. For example:</p>
+
+ <blockquote>
+ <pre>struct functor {
+ template&lt;class&gt; struct result;
+ template&lt;class F, class T&gt; struct result&lt;F(const T)&gt; {
+ typedef const T type;
+ };
+
+ const short operator()(const short);
+ int const & operator()(int const &);
+};
+
+// Non-prvalue call expressions work the same with or without decltype.
+
+BOOST_STATIC_ASSERT((
+ boost::is_same&lt;
+ boost::result_of&lt;functor(int const &)&gt;::type,
+ int const &
+::value
+));
+
+// Non-class prvalue call expressions are not actually cv-qualified,
+// but only the decltype-based result_of reports this accurately.
+
+#ifdef BOOST_RESULT_OF_USE_DECLTYPE
+
+BOOST_STATIC_ASSERT((
+ boost::is_same&lt;
+ boost::result_of&lt;functor(const short)&gt;::type,
+ short
+::value
+));
+
+#else
+
+BOOST_STATIC_ASSERT((
+ boost::is_same&lt;
+ boost::result_of&lt;functor(const short)&gt;::type,
+ const short
+::value
+));
+
+#endif</pre>
+ </blockquote></li>
+ </ul>
+
+ <a name="result_of_cxx11_diff">
+ <h3>Known differences between boost::result_of and C++11 result_of</h3>
+ </a>
+
+ <p>When using <code>decltype</code>, <code>boost::result_of</code>
+ implements most of the C++11 result_of
+ specification. One known exception is that
+ <code>boost::result_of</code> does not implement the
+ requirements regarding pointers to member data.</p>
+
+ <p>Created by Doug Gregor. Contributions from Daniel Walker, Eric Niebler, Michel Morin and others</p>
+
+ <h2><a name="BOOST_BINARY">Macro BOOST_BINARY</a></h2>
+
+ <p>The macro <code>BOOST_BINARY</code> is used for the
+ representation of binary literals. It takes as an argument
+ a binary number arranged as an arbitrary amount of 1s and 0s in
+ groupings of length 1 to 8, with groups separated
+ by spaces. The type of the literal yielded is determined by
+ the same rules as those of hex and octal
+ literals (<i>2.13.1p1</i>). By implementation, this macro
+ expands directly to an octal literal during preprocessing, so
+ there is no overhead at runtime and the result is useable in
+ any place that an octal literal would be.</p>
+
+ <p>In order to directly support binary literals with suffixes,
+ additional macros of the form BOOST_BINARY_XXX are also
+ provided, where XXX is a standard integer suffix in all capital
+ letters. In addition, LL and ULL suffixes may be used for representing
+ long long and unsigned long long types in compilers which provide
+ them as an extension.</p>
+
+
+ <p>The BOOST_BINARY family of macros resides in the header
+ <a
+ href="../../boost/utility/binary.hpp">&lt;boost/utility/binary.hpp&gt;</a>
+ which is automatically included by
+ <a
+ href="../../boost/utility.hpp">&lt;boost/utility.hpp&gt;</a>.
+
+ <p>Contributed by Matt Calabrese.</p><p>
+ </p><h3>Example</h3>
+ <blockquote>
+ <pre>
+void foo( int );
+
+void foo( unsigned long );
+
+void bar()
+{
+ int value1 = BOOST_BINARY( 100 111000 01 1 110 );
+
+ unsigned long value2 = BOOST_BINARY_UL( 100 001 ); // unsigned long
+
+ long long value3 = BOOST_BINARY_LL( 11 000 ); // long long if supported
+
+ assert( BOOST_BINARY( 10010 )
+ & BOOST_BINARY( 11000 )
+ == BOOST_BINARY( 10000 )
+ );
+
+ foo( BOOST_BINARY( 1010 ) ); // calls the first foo
+
+ foo( BOOST_BINARY_LU( 1010 ) ); // calls the second foo
+}
+</pre></blockquote>
+ <hr>
+ <p>Revised&nbsp; <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan
+-->04 September, 2008<!--webbot bot="Timestamp" endspan i-checksum="39369"
+-->
+ </p>
+ <p>&copy; Copyright Beman Dawes 1999-2003.</p>
+<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>
+
+ </body>
+</html>
diff --git a/src/boost/libs/utility/value_init.htm b/src/boost/libs/utility/value_init.htm
new file mode 100644
index 000000000..3222f691c
--- /dev/null
+++ b/src/boost/libs/utility/value_init.htm
@@ -0,0 +1,514 @@
+<html>
+<head>
+
+ <meta http-equiv="Content-Type"
+ content="text/html; charset=iso-8859-1">
+ <title>value_initialized</title>
+
+</head>
+ <body vlink="#800080" link="#0000ff" text="#000000" bgcolor="#ffffff">
+
+<h2><img src="../../boost.png" width="276" height="86">
+ Header &lt;<a href="../../boost/utility/value_init.hpp">boost/utility/value_init.hpp</a>&gt;
+ </h2>
+
+<h2>Contents</h2>
+
+<dl>
+ <dt><a href="#rationale">Rationale</a></dt>
+ <dt><a href="#intro">Introduction</a></dt>
+ <dt><a href="#details">Details</a></dt>
+</dl>
+
+<ul>
+ <li><a href="#valueinit">value-initialization</a></li>
+ <li><a href="#valueinitsyn">value-initialization syntax</a></li>
+ <li><a href="#compiler_issues">compiler issues</a></li>
+
+</ul>
+
+<dl class="page-index">
+ <dt><a href="#types">Types and objects</a></dt>
+</dl>
+
+<ul>
+ <li><a href="#val_init"><code>template class value_initialized&lt;T&gt;</code></a></li>
+ <li><a href="#initialized"><code>template class initialized&lt;T&gt;</code></a></li>
+ <li><a href="#initialized_value"><code>initialized_value</code></a></li>
+
+</ul>
+ <a href="#acknowledgements">Acknowledgements</a><br>
+ <br>
+
+<hr>
+<h2><a name="rationale"></a>Rationale</h2>
+
+<p>Constructing and initializing objects in a generic way is difficult in
+ C++. The problem is that there are several different rules that apply
+for initialization. Depending on the type, the value of a newly constructed
+ object can be zero-initialized (logically 0), default-constructed (using
+ the default constructor), or indeterminate. When writing generic code,
+this problem must be addressed. The template <code>value_initialized</code> provides
+a solution with consistent syntax for value initialization of scalar,
+union and class types.
+Moreover, <code>value_initialized</code> offers a workaround to various
+compiler issues regarding value-initialization.
+
+Furthermore, a <code>const</code> object, <code>initialized_value</code> is provided,
+to avoid repeating the type name when retrieving the value from a
+<code>value_initialized&lt;T&gt;</code> object.
+<br>
+ </p>
+
+<h2><a name="intro"></a>Introduction</h2>
+
+<p>
+There are various ways to initialize a variable, in C++. The following
+declarations all <em>may</em> have a local variable initialized to its default
+value:
+<pre>
+ T1 var1;
+ T2 var2 = 0;
+ T3 var3 = {};
+ T4 var4 = T4();
+</pre>
+Unfortunately, whether or not any of those declarations correctly
+initialize the variable very much depends on its type. The first
+declaration is valid for any <a href="http://www.sgi.com/tech/stl/DefaultConstructible.html">
+DefaultConstructible</a> type (by definition).
+However, it does not always do an initialization!
+It correctly initializes the variable when it's an instance of a
+class, and the author of the class has provided a proper default
+constructor. On the other hand, the value of <code>var1</code> is <em>indeterminate</em> when
+its type is an arithmetic type, like <code>int</code>, <code>float</code>, or <code>char</code>.
+An arithmetic variable
+is of course initialized properly by the second declaration, <code>T2
+var2 = 0</code>. But this initialization form usually won't work for a
+class type (unless the class was especially written to support being
+initialized that way). The third form, <code>T3 var3 = {}</code>
+initializes an aggregate, typically a "C-style" <code>struct</code> or a "C-style" array.
+However, the syntax is not allowed for a class that has an explicitly declared
+constructor. (But watch out for an upcoming C++ language change,
+by Bjarne Stroustrup et al [<a href="#references">1</a>]!)
+The fourth form is the most generic form of them, as it
+can be used to initialize arithmetic types, class types, aggregates, pointers, and
+other types. The declaration, <code>T4 var4 = T4()</code>, should be read
+as follows: First a temporary object is created, by <code>T4()</code>.
+This object is <a href="#valueinit">value-initialized</a>. Next the temporary
+object is copied to the named variable, <code>var4</code>. Afterwards, the temporary
+is destroyed. While the copying and the destruction are likely to
+be optimized away, C++ still requires the type <code>T4</code> to be
+<a href="CopyConstructible.html">CopyConstructible</a>.
+(So <code>T4</code> needs to be <em>both</em> DefaultConstructible <em>and</em> CopyConstructible.)
+A class may not be CopyConstructible, for example because it may have a
+private and undefined copy constructor,
+or because it may be derived from <a href="utility.htm#Class_noncopyable">boost::noncopyable</a>.
+Scott Meyers [<a href="#references">2</a>] explains why a class would be defined like that.
+</p>
+<p>
+There is another, less obvious disadvantage to the fourth form, <code>T4 var4 = T4()</code>:
+It suffers from various <a href="#compiler_issues">compiler issues</a>, causing
+a variable to be left uninitialized in some compiler specific cases.
+</p>
+<p>
+The template <a href="#val_init"><code>value_initialized</code></a>
+offers a generic way to initialize
+an object, like <code>T4 var4 = T4()</code>, but without requiring its type
+to be CopyConstructible. And it offers a workaround to those compiler issues
+regarding value-initialization as well! It allows getting an initialized
+variable of any type; it <em>only</em> requires the type to be DefaultConstructible.
+A properly <em>value-initialized</em> object of type <code>T</code> is
+constructed by the following declaration:
+<pre>
+ value_initialized&lt;T&gt; var;
+</pre>
+</p>
+<p>
+The template <a href="#initialized"><code>initialized</code></a>
+offers both value-initialization and direct-initialization.
+It is especially useful as a data member type, allowing the very same object
+to be either direct-initialized or value-initialized.
+</p>
+<p>
+The <code>const</code> object <a href="#initialized_value"><code>initialized_value</code></a>
+allows value-initializing a variable as follows:
+<pre>
+ T var = initialized_value ;
+</pre>
+This form of initialization is semantically equivalent to <code>T4 var4 = T4()</code>,
+but robust against the aforementioned compiler issues.
+
+</p>
+
+<h2><a name="details"></a>Details</h2>
+<p>The C++ standard [<a href="#references">3</a>] contains the definitions
+ of <code>zero-initialization</code> and <code>default-initialization</code>.
+ Informally, zero-initialization means that the object is given the initial
+ value 0 (converted to the type) and default-initialization means that
+ POD [<a href="#references">4</a>] types are zero-initialized, while non-POD class
+ types are initialized with their corresponding default constructors. A
+<i>declaration</i> can contain an <i>initializer</i>, which specifies the
+object's initial value. The initializer can be just '()', which states that
+the object shall be value-initialized (but see below). However, if a <i>declaration</i>
+ has no <i>initializer</i> and it is of a non-<code>const</code>, non-<code>static</code>
+ POD type, the initial value is indeterminate: <cite>(see &sect;8.5, [dcl.init], for the
+ accurate definitions).</cite></p>
+
+<pre>int x ; // no initializer. x value is indeterminate.<br>std::string s ; // no initializer, s is default-constructed.<br><br>int y = int() ; <br>// y is initialized using copy-initialization<br>// but the temporary uses an empty set of parentheses as the initializer,<br>// so it is default-constructed.<br>// A default constructed POD type is zero-initialized,<br>// therefore, y == 0.<br><br>void foo ( std::string ) ;<br>foo ( std::string() ) ; <br>// the temporary string is default constructed <br>// as indicated by the initializer () </pre>
+
+<h3><a name="valueinit">value-initialization</a></h3>
+
+<p>The first <a
+ href="http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html">Technical
+ Corrigendum for the C++ Standard</a> (TC1), whose draft was released to
+ the public in November 2001, introduced <a
+ href="http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#178">Core
+ Issue 178</a> (among many other issues, of course).</p>
+
+<p> That issue introduced the new concept of <code>value-initialization</code>
+ (it also fixed the wording for zero-initialization). Informally, value-initialization
+ is similar to default-initialization with the exception that in some cases
+ non-static data members and base class sub-objects are also value-initialized.
+ The difference is that an object that is value-initialized won't have
+(or at least is less likely to have) indeterminate values for data members
+ and base class sub-objects; unlike the case of an object default constructed.
+ (see Core Issue 178 for a normative description).</p>
+
+<p>In order to specify value-initialization of an object we need to use the
+ empty-set initializer: (). </p>
+
+<p>As before, a declaration with no intializer specifies default-initialization,
+ and a declaration with a non-empty initializer specifies copy (=xxx) or
+ direct (xxx) initialization. </p>
+
+<pre>template&lt;class T&gt; void eat(T);<br>int x ; // indeterminate initial value.<br>std::string s; // default-initialized.<br>eat ( int() ) ; // value-initialized<br>eat ( std::string() ) ; // value-initialized</pre>
+
+<h4><a name="valueinitsyn">value-initialization</a> syntax</h4>
+
+<p>Value initialization is specified using (). However, the empty set of
+parentheses is not permitted by the syntax of initializers because it is
+parsed as the declaration of a function taking no arguments: </p>
+
+<pre>int x() ; // declares function int(*)()</pre>
+
+<p>Thus, the empty () must be put in some other initialization context.</p>
+
+<p>One alternative is to use copy-initialization syntax:</p>
+
+<pre>int x = int() ;</pre>
+
+<p>This works perfectly fine for POD types. But for non-POD class types,
+copy-initialization searches for a suitable constructor, which could be,
+for instance, the copy-constructor (it also searches for a suitable conversion
+sequence but this doesn't apply in this context). For an arbitrary unknown
+type, using this syntax may not have the value-initialization effect intended
+because we don't know if a copy from a default constructed object is exactly
+the same as a default constructed object, and the compiler is allowed (in
+some cases), but never required to, optimize the copy away.</p>
+
+<p>One possible generic solution is to use value-initialization of a non static
+data member:</p>
+
+<pre>template&lt;class T&gt; <br>struct W <br>{<br> // value-initialization of 'data' here.<br> W() : data() {}<br> T data ;<br>} ;<br>W&lt;int&gt; w ;<br>// w.data is value-initialized for any type. </pre>
+
+<p>This is the solution as it was supplied by earlier versions of the
+<code>value_initialized&lt;T&gt;</code> template
+ class. Unfortunately this approach suffered from various compiler issues.</p>
+
+<h4><a name="compiler_issues">compiler issues</a> </h4>
+
+Various compilers haven't yet fully implemented value-initialization.
+So when an object should be <em>value-initialized</em> (according to the C++ Standard),
+it <em>may</em> in practice still be left uninitialized, because of those
+compiler issues! It's hard to make a general statement on what those issues
+are like, because they depend on the compiler you are using, its version number,
+and the type of object you would like to have value-initialized.
+All compilers we have tested so far support value-initialization for arithmetic types properly.
+However, various compilers may leave some types of <em>aggregates</em> uninitialized, when they
+should be value-initialized. Value-initialization of objects of a pointer-to-member type may also
+go wrong on various compilers.
+</p>
+<p>
+At the moment of writing, May 2010, the following reported issues regarding
+value-initialization are still there in current compiler releases:
+<ul>
+<li>
+<a href="https://connect.microsoft.com/VisualStudio/feedback/details/100744">
+Microsoft Visual Studio Feedback ID 100744, Value-initialization in new-expression</a>
+<br>Reported by Pavel Kuznetsov (MetaCommunications Engineering), 2005
+</li><li>
+<a href="http://connect.microsoft.com/VisualStudio/feedback/details/484295">
+Microsoft Visual Studio Feedback ID 484295, VC++ does not value-initialize members of derived classes without user-declared constructor</a>
+<br>Reported by Sylvester Hesp, 2009
+</li><li>
+<a href="https://connect.microsoft.com/VisualStudio/feedback/details/499606">
+Microsoft Visual Studio Feedback ID 499606, Presence of copy constructor breaks member class initialization</a>
+<br>Reported by Alex Vakulenko, 2009
+</li><li>
+<a href="http://qc.embarcadero.com/wc/qcmain.aspx?d=83751">
+Embarcadero/C++Builder Report 83751, Value-initialization: arrays should have each element value-initialized</a>
+<br>Reported by Niels Dekker (LKEB), 2010
+</li><li>
+<a href="http://qc.embarcadero.com/wc/qcmain.aspx?d=83851">
+Embarcadero/C++Builder Report 83851, Value-initialized temporary triggers internal backend error C1798</a>
+<br>Reported by Niels Dekker, 2010
+</li><li>
+<a href="http://qc.embarcadero.com/wc/qcmain.aspx?d=84279">
+Embarcadero/C++Builder Report 84279, Internal compiler error (F1004), value-initializing member function pointer by "new T()"</a>
+<br>Reported by Niels Dekker, 2010
+</li><li>
+Sun CR 6947016, Sun 5.10 may fail to value-initialize an object of a non-POD aggregate.
+<br>Reported to Steve Clamage by Niels Dekker, 2010
+</li><li>
+IBM's XL V10.1 and V11.1 may fail to value-initialize a temporary of a non-POD aggregate.
+<br>Reported to Michael Wong by Niels Dekker, 2010
+</li><li>
+Intel support issue 589832, Attempt to value-initialize pointer-to-member triggers internal error
+on Intel 11.1.
+<br>Reported by John Maddock, 2010
+</li>
+</ul>
+Note that all known GCC issues regarding value-initialization are
+fixed with GCC version 4.4, including
+<a href="http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30111">GCC Bug 30111</a>.
+Clang also has completely implemented value-initialization, as far as we know,
+now that <a href="http://llvm.org/bugs/show_bug.cgi?id=7139">Clang Bug 7139</a> is fixed.
+</p><p>
+
+New versions of <code>value_initialized</code>
+(Boost release version 1.35 or higher)
+offer a workaround to these issues: <code>value_initialized</code> may now clear
+its internal data, prior to constructing the object that it contains. It will do
+so for those compilers that need to have such a workaround, based on the
+<a href="../config/doc/html/boost_config/boost_macro_reference.html#boost_config.boost_macro_reference.macros_that_describe_defects"
+>compiler defect macro</a> BOOST_NO_COMPLETE_VALUE_INITIALIZATION.
+</p>
+
+<h2><a name="types"></a>Types and objects</h2>
+
+<h2><a name="val_init"><code>template class value_initialized&lt;T&gt;</code></a></h2>
+
+<pre>namespace boost {<br><br>template&lt;class T&gt;<br>class value_initialized<br>{
+<br> public :
+<br> value_initialized() : x() {}
+<br> operator T const &amp;() const { return x ; }
+<br> operator T&amp;() { return x ; }
+<br> T const &amp;data() const { return x ; }
+<br> T&amp; data() { return x ; }
+<br> void swap( value_initialized&amp; );
+<br>
+<br> private :
+<br> <i>unspecified</i> x ;
+<br>} ;
+<br>
+<br>template&lt;class T&gt;
+<br>T const&amp; get ( value_initialized&lt;T&gt; const&amp; x )
+<br>{
+<br> return x.data() ;
+<br>}
+<br>
+<br>template&lt;class T&gt;
+<br>T&amp; get ( value_initialized&lt;T&gt;&amp; x )
+<br>{
+<br> return x.data() ;
+<br>}
+<br>
+<br>template&lt;class T&gt;
+<br>void swap ( value_initialized&lt;T&gt;&amp; lhs, value_initialized&lt;T&gt;&amp; rhs )
+<br>{
+<br> lhs.swap(rhs) ;
+<br>}
+<br>
+<br>} // namespace boost
+<br></pre>
+
+<p>An object of this template class is a <code>T</code>-wrapper convertible
+ to <code>'T&amp;'</code> whose wrapped object (data member of type <code>T</code>)
+ is <a href="#valueinit">value-initialized</a> upon default-initialization
+ of this wrapper class: </p>
+
+<pre>int zero = 0 ;<br>value_initialized&lt;int&gt; x ;<br>assert ( x == zero ) ;<br><br>std::string def ;<br>value_initialized&lt; std::string &gt; y ;<br>assert ( y == def ) ;<br></pre>
+
+<p>The purpose of this wrapper is to provide a consistent syntax for value
+ initialization of scalar, union and class types (POD and non-POD) since
+ the correct syntax for value initialization varies (see <a
+ href="#valueinitsyn">value-initialization syntax</a>)</p>
+
+<p>The wrapped object can be accessed either through the conversion operator
+ <code>T&amp;</code>, the member function <code>data()</code>, or the
+non-member function <code>get()</code>: </p>
+
+<pre>void watch(int);<br>value_initialized&lt;int&gt; x;
+<br><br>watch(x) ; // operator T&amp; used.<br>watch(x.data());<br>watch( get(x) ) // function get() used</pre>
+
+<p>Both <code>const</code> and non-<code>const</code> objects can be wrapped.
+ Mutable objects can be modified directly from within the wrapper but constant
+ objects cannot:</p>
+
+<p>When <code>T</code> is a <em>Swappable</em> type, <code>value_initialized&lt;T&gt;</code>
+ is swappable as well, by calling its <code>swap</code> member function
+ as well as by calling <code>boost::swap</code>.</p>
+
+<pre>value_initialized&lt;int&gt; x ; <br>static_cast&lt;int&amp;&gt;(x) = 1 ; // OK<br>get(x) = 1 ; // OK
+<br><br>value_initialized&lt;int const&gt; y ; <br>static_cast&lt;int&amp;&gt;(y) = 1 ; // ERROR: cannot cast to int&amp;<br>static_cast&lt;int const&amp;&gt;(y) = 1 ; // ERROR: cannot modify a const value<br>get(y) = 1 ; // ERROR: cannot modify a const value</pre>
+
+<h3>Warning:</h3>
+
+<p>The <code>value_initialized</code> implementation of Boost version 1.40.0 and older
+allowed <i>non-const</i> access to the wrapped object, from a constant wrapper,
+both by its conversion operator and its <code>data()</code> member function. For example:</p>
+
+<pre>value_initialized&lt;int&gt; const x_c ;<br>int&amp; xr = x_c ; // OK, conversion to int&amp; available even though x_c is itself const.
+<br>xr = 2 ; </pre>
+
+<p>The reason for this obscure behavior was that some compilers
+ didn't accept the following valid code:</p>
+
+<pre>struct X<br>{<br> operator int&amp;() ;<br> operator int const&amp;() const ; <br>};<br>X x ;<br>(x == 1 ) ; // ERROR HERE!</pre>
+
+<p>The current version of <code>value_initialized</code> no longer has this obscure behavior.
+As compilers nowadays widely support overloading the conversion operator by having a <code>const</code> and a <code>non-const</code> version, we have decided to fix the issue accordingly. So the current version supports the idea of logical constness.
+<br>
+ </p>
+
+<h3>Recommended practice: The non-member get() idiom</h3>
+
+<p>The obscure behavior of being able to modify a non-<code>const</code>
+wrapped object from within a constant wrapper (as was supported by previous
+versions of <code>value_initialized</code>)
+can be avoided if access to
+the wrapped object is always performed with the <code>get()</code> idiom:</p>
+
+<pre>value_initialized&lt;int&gt; x ;<br>get(x) = 1 ; // OK<br><br>value_initialized&lt;int const&gt; cx ;<br>get(x) = 1 ; // ERROR: Cannot modify a const object<br><br>value_initialized&lt;int&gt; const x_c ;<br>get(x_c) = 1 ; // ERROR: Cannot modify a const object<br><br>value_initialized&lt;int const&gt; const cx_c ;<br>get(cx_c) = 1 ; // ERROR: Cannot modify a const object<br></pre>
+
+<h2><a name="initialized"><code>template class initialized&lt;T&gt;</code></a></h2>
+
+<pre>namespace boost {<br><br>template&lt;class T&gt;<br>class initialized<br>{
+<br> public :
+<br> initialized() : x() {}
+<br> explicit initialized(T const &amp; arg) : x(arg) {}
+<br> operator T const &amp;() const;
+<br> operator T&amp;();
+<br> T const &amp;data() const;
+<br> T&amp; data();
+<br> void swap( initialized&amp; );
+<br>
+<br> private :
+<br> <i>unspecified</i> x ;
+<br>} ;
+<br>
+<br>template&lt;class T&gt;
+<br>T const&amp; get ( initialized&lt;T&gt; const&amp; x );
+<br>
+<br>template&lt;class T&gt;
+<br>T&amp; get ( initialized&lt;T&gt;&amp; x );
+<br>
+<br>template&lt;class T&gt;
+<br>void swap ( initialized&lt;T&gt;&amp; lhs, initialized&lt;T&gt;&amp; rhs );
+<br>
+<br>} // namespace boost
+<br></pre>
+
+The template class <code>boost::initialized&lt;T&gt;</code> supports both value-initialization
+and direct-initialization, so its interface is a superset of the interface
+of <code>value_initialized&lt;T&gt;</code>: Its default-constructor
+value-initializes the wrapped object just like the default-constructor of
+<code>value_initialized&lt;T&gt;</code>, but <code>boost::initialized&lt;T&gt;</code>
+also offers an extra <code>explicit</code>
+constructor, which direct-initializes the wrapped object by the specified value.
+<p>
+
+<code>initialized&lt;T&gt;</code> is especially useful when the wrapped
+object must be either value-initialized or direct-initialized, depending on
+runtime conditions. For example, <code>initialized&lt;T&gt;</code> could
+hold the value of a data member that may be value-initialized by some
+constructors, and direct-initialized by others.
+On the other hand, if it is known beforehand that the
+object must <i>always</i> be value-initialized, <code>value_initialized&lt;T&gt;</code>
+may be preferable. And if the object must always be
+direct-initialized, none of the two wrappers really needs to be used.
+</p>
+
+
+<h2><a name="initialized_value"><code>initialized_value</code></a></h2>
+
+<pre>
+namespace boost {
+class initialized_value_t
+{
+ public :
+ template &lt;class T&gt; operator T() const ;
+};
+
+initialized_value_t const initialized_value = {} ;
+
+} // namespace boost
+</pre>
+
+<code>initialized_value</code> provides a convenient way to get
+an initialized value: its conversion operator provides an appropriate
+<em>value-initialized</em> object for any CopyConstructible type.
+
+Suppose you need to have an initialized variable of type <code>T</code>.
+You could do it as follows:
+<pre>
+ T var = T();
+</pre>
+But as mentioned before, this form suffers from various compiler issues.
+The template <code>value_initialized</code> offers a workaround:
+<pre>
+ T var = get( value_initialized&lt;T&gt;() );
+</pre>
+Unfortunately both forms repeat the type name, which
+is rather short now (<code>T</code>), but could of course be
+more like <code>Namespace::Template&lt;Arg&gt;::Type</code>.
+Instead, one could use <code>initialized_value</code> as follows:
+<pre>
+ T var = initialized_value ;
+</pre>
+
+<h3><a name="references">References</a></h3>
+ [1] Bjarne Stroustrup, Gabriel Dos Reis, and J. Stephen Adamczyk wrote
+ various papers, proposing to extend the support for brace-enclosed <em>initializer lists</em>
+ in the next version of C++.
+ This would allow a variable <code>var</code> of any DefaultConstructible type
+ <code>T</code> to be <em>value-initialized</em> by doing <code>T var = {}</code>.
+ The papers are listed at Bjarne's web page,
+ <a href="http://www.research.att.com/~bs/WG21.html">My C++ Standards committee papers</a> <br>
+ [2] Scott Meyers, Effective C++, Third Edition, item 6,
+ <em>Explicitly disallow the use of compiler-generated functions you do not want</em>,
+ <a href="http://www.aristeia.com/books.html">Scott Meyers: Books and CDs</a> <br>
+ [3] The C++ Standard, Second edition (2003), ISO/IEC 14882:2003 <br>
+ [4] POD stands for "Plain Old Data"
+
+<h3><a name="acknowledgements"></a>Acknowledgements</h3>
+ value_initialized was developed by Fernando Cacciola, with help and
+suggestions from David Abrahams and Darin Adler.<br>
+Special thanks to Bj&ouml;rn Karlsson who carefully edited and completed this documentation.
+
+<p>value_initialized was reimplemented by Fernando Cacciola and Niels Dekker
+for Boost release version 1.35 (2008), offering a workaround to various compiler issues.
+ </p>
+<p><code>boost::initialized</code> was very much inspired by feedback from Edward Diener and
+ Jeffrey Hellrung.
+ </p>
+<p>initialized_value was written by Niels Dekker, and added to Boost release version 1.36 (2008).
+ </p>
+<p>Developed by <a href="mailto:fernando_cacciola@hotmail.com">Fernando Cacciola</a>,
+ the latest version of this file can be found at <a
+ href="http://www.boost.org">www.boost.org</a>.
+ </p>
+
+<hr>
+<p>Revised 30 May 2010</p>
+
+<p>&copy; Copyright Fernando Cacciola, 2002 - 2010.</p>
+
+<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>
+
+ <br>
+ <br>
+
+</body>
+</html>