mirror of
https://github.com/boostorg/utility.git
synced 2025-10-12 00:25:19 +02:00
Compare commits
85 Commits
svn-branch
...
svn-branch
Author | SHA1 | Date | |
---|---|---|---|
|
59f15390a9 | ||
|
dd80a4f8ec | ||
|
2a50eba072 | ||
|
1770e47f97 | ||
|
d4f4893ee1 | ||
|
23ec8fc788 | ||
|
3ab8d14a59 | ||
|
9f10fc03ce | ||
|
84fbb3c896 | ||
|
865c707756 | ||
|
871f3a6779 | ||
|
aaca5ca871 | ||
|
5a4e19989f | ||
|
6ea398c446 | ||
|
1bd83d43e8 | ||
|
5ca5b4102b | ||
|
aca7699046 | ||
|
e702a944ca | ||
|
a157c345ee | ||
|
dcb2dd4736 | ||
|
ae19cd6236 | ||
|
3ab4d38931 | ||
|
18c7fb72b5 | ||
|
6bb092a9b1 | ||
|
f721b8b28c | ||
|
e5ba34472d | ||
|
082ae17eaf | ||
|
dd86e09ab4 | ||
|
baff23116e | ||
|
e549baf93a | ||
|
30d46adcb7 | ||
|
e854726be0 | ||
|
d198bd9d96 | ||
|
5eb23cecd0 | ||
|
eff2c75bba | ||
|
325bd73df7 | ||
|
0fcc554abd | ||
|
b685784155 | ||
|
ac90fdc611 | ||
|
51077e49f5 | ||
|
0c3199f72d | ||
|
62675a3bcd | ||
|
c26dbaa620 | ||
|
8201624959 | ||
|
f2116413d6 | ||
|
b0baebeb0a | ||
|
fb943b77d5 | ||
|
b4b39510fc | ||
|
6f0f05ba12 | ||
|
f0b64b6229 | ||
|
4229488989 | ||
|
acd2e6ef2b | ||
|
c26aaed71f | ||
|
326d7ad4d7 | ||
|
c76a2f4aab | ||
|
d8b0ff2d7e | ||
|
996ce2d307 | ||
|
167fa4154f | ||
|
0c7e7c3c39 | ||
|
9d8f8f41dc | ||
|
39c4445b39 | ||
|
7819b022ad | ||
|
65d27e7f86 | ||
|
212a70bf77 | ||
|
6b5dc18a46 | ||
|
0917f83b9c | ||
|
7322bd3903 | ||
|
e998010184 | ||
|
918a1c93e4 | ||
|
14c87853c2 | ||
|
d5a5b84a40 | ||
|
35d3c03d19 | ||
|
8933fbb254 | ||
|
c320330cd5 | ||
|
822b46a3df | ||
|
a821ef6e2c | ||
|
491db15997 | ||
|
b6c826a139 | ||
|
7b472a05ee | ||
|
9a07bc0d9b | ||
|
154d6bb198 | ||
|
0dde936e61 | ||
|
918bf25039 | ||
|
04fda4fb4e | ||
|
e14a250d6e |
@@ -15,7 +15,7 @@
|
||||
</HEAD>
|
||||
<BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"
|
||||
ALINK="#ff0000">
|
||||
<IMG SRC="../../c++boost.gif"
|
||||
<IMG SRC="../../boost.png"
|
||||
ALT="C++ Boost" width="277" height="86">
|
||||
<!--end header-->
|
||||
<BR Clear>
|
||||
|
@@ -17,7 +17,7 @@
|
||||
<BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"
|
||||
ALINK="#ff0000">
|
||||
<h1>
|
||||
<img src="../../c++boost.gif" alt="boost logo"
|
||||
<img src="../../boost.png" alt="boost logo"
|
||||
width="277" align="middle" height="86">
|
||||
<br>Collection
|
||||
</h1>
|
||||
|
@@ -15,7 +15,7 @@
|
||||
</HEAD>
|
||||
<BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"
|
||||
ALINK="#ff0000">
|
||||
<IMG SRC="../../c++boost.gif"
|
||||
<IMG SRC="../../boost.png"
|
||||
ALT="C++ Boost" width="277" height="86">
|
||||
<!--end header-->
|
||||
<BR Clear>
|
||||
|
@@ -39,7 +39,7 @@
|
||||
</Head>
|
||||
<BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"
|
||||
ALINK="#ff0000">
|
||||
<IMG SRC="../../c++boost.gif"
|
||||
<IMG SRC="../../boost.png"
|
||||
ALT="C++ Boost" width="277" height="86">
|
||||
<!--end header-->
|
||||
<BR Clear>
|
||||
|
@@ -14,7 +14,7 @@
|
||||
<Title>MultiPassInputIterator</Title>
|
||||
<BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"
|
||||
ALINK="#ff0000">
|
||||
<IMG SRC="../../c++boost.gif"
|
||||
<IMG SRC="../../boost.png"
|
||||
ALT="C++ Boost" width="277" height="86">
|
||||
|
||||
<BR Clear>
|
||||
@@ -30,9 +30,9 @@ 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.hmtl">Forward Iterator</a>. The
|
||||
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.hmtl">Forward Iterator</a>
|
||||
href="http://www.sgi.com/tech/stl/ForwardIterator.html">Forward Iterator</a>
|
||||
requires the <TT>reference</TT> type to be <TT>value_type&</TT>, whereas
|
||||
MultiPassInputIterator is like <a
|
||||
href="http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a>
|
||||
|
@@ -4,7 +4,7 @@
|
||||
</HEAD>
|
||||
<BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"
|
||||
ALINK="#ff0000">
|
||||
<IMG SRC="../../c++boost.gif"
|
||||
<IMG SRC="../../boost.png"
|
||||
ALT="C++ Boost" width="277" height="86">
|
||||
<!--end header-->
|
||||
<BR Clear>
|
||||
@@ -115,10 +115,9 @@ struct equal_pointees_t : std::binary_function<OptionalPointee,OptionalPointe
|
||||
} ;
|
||||
</pre>
|
||||
<p>The preceding generic function and function object have the following semantics:<br>
|
||||
If both x and y have valid pointees, it compares values via (*x == *y) or (*x <
|
||||
*y).<br>
|
||||
If only one has a valid pointee, returns false.<br>
|
||||
If both have invalid pointees, returns true.</p>
|
||||
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<class OptionalPointee>
|
||||
@@ -135,11 +134,12 @@ struct less_pointees_t : std::binary_function<OptionalPointee,OptionalPointee
|
||||
} ;
|
||||
</pre>
|
||||
<p>The preceding generic function and function object have the following semantics:<br>
|
||||
If both x and y have valid pointees, it compares values via (*x == *y) or (*x <
|
||||
*y).<br>
|
||||
If only one has a valid pointee, returns false.<br>
|
||||
If both have invalid pointees, returns false.</p>
|
||||
<p>All these functions and function
|
||||
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 <
|
||||
*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<> for instance does not alias);
|
||||
so direct usage of relational operators with the implied aliasing of shallow semantics
|
||||
|
@@ -1,46 +1,94 @@
|
||||
// Copyright (C) 2002 Brad King (brad.king@kitware.com)
|
||||
// Doug Gregor (gregod@cs.rpi.edu)
|
||||
// Douglas Gregor (gregod@cs.rpi.edu)
|
||||
//
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
// 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
|
||||
|
||||
#define BOOST_INCLUDE_MAIN
|
||||
#include <boost/test/test_tools.hpp>
|
||||
#include <boost/utility.hpp>
|
||||
|
||||
#include <boost/utility/addressof.hpp>
|
||||
|
||||
#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300)
|
||||
#pragma warning(push, 3)
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
template<class T> void scalar_test( T * = 0 )
|
||||
{
|
||||
T* px = new T();
|
||||
|
||||
T& x = *px;
|
||||
BOOST_TEST( boost::addressof(x) == px );
|
||||
|
||||
const T& cx = *px;
|
||||
const T* pcx = boost::addressof(cx);
|
||||
BOOST_TEST( pcx == px );
|
||||
|
||||
volatile T& vx = *px;
|
||||
volatile T* pvx = boost::addressof(vx);
|
||||
BOOST_TEST( pvx == px );
|
||||
|
||||
const volatile T& cvx = *px;
|
||||
const volatile T* pcvx = boost::addressof(cvx);
|
||||
BOOST_TEST( pcvx == px );
|
||||
|
||||
delete px;
|
||||
}
|
||||
|
||||
template<class T> void array_test( T * = 0 )
|
||||
{
|
||||
T nrg[3] = {1,2,3};
|
||||
T (*pnrg)[3] = &nrg;
|
||||
BOOST_TEST( boost::addressof(nrg) == pnrg );
|
||||
|
||||
T const cnrg[3] = {1,2,3};
|
||||
T const (*pcnrg)[3] = &cnrg;
|
||||
BOOST_TEST( boost::addressof(cnrg) == pcnrg );
|
||||
}
|
||||
|
||||
struct addressable
|
||||
{
|
||||
addressable( int = 0 )
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct useless_type {};
|
||||
|
||||
class nonaddressable {
|
||||
public:
|
||||
void dummy(); // Silence GCC warning: all member of class are private
|
||||
|
||||
nonaddressable( int = 0 )
|
||||
{
|
||||
}
|
||||
|
||||
void dummy(); // Silence GCC warning: all member of class are private
|
||||
|
||||
private:
|
||||
useless_type operator&() const;
|
||||
|
||||
useless_type operator&() const;
|
||||
};
|
||||
|
||||
int test_main(int, char*[])
|
||||
int main()
|
||||
{
|
||||
nonaddressable* px = new nonaddressable();
|
||||
scalar_test<char>();
|
||||
scalar_test<int>();
|
||||
scalar_test<addressable>();
|
||||
scalar_test<nonaddressable>();
|
||||
|
||||
nonaddressable& x = *px;
|
||||
BOOST_TEST(boost::addressof(x) == px);
|
||||
array_test<char>();
|
||||
array_test<int>();
|
||||
array_test<addressable>();
|
||||
array_test<nonaddressable>();
|
||||
|
||||
const nonaddressable& cx = *px;
|
||||
BOOST_TEST(boost::addressof(cx) == static_cast<const nonaddressable*>(px));
|
||||
|
||||
volatile nonaddressable& vx = *px;
|
||||
BOOST_TEST(boost::addressof(vx) == static_cast<volatile nonaddressable*>(px));
|
||||
|
||||
const volatile nonaddressable& cvx = *px;
|
||||
BOOST_TEST(boost::addressof(cvx) == static_cast<const volatile nonaddressable*>(px));
|
||||
|
||||
return 0;
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
@@ -8,7 +8,7 @@
|
||||
<table border="0" width="100%">
|
||||
<tr>
|
||||
<td width="277">
|
||||
<img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" width="277" height="86">
|
||||
<img src="../../boost.png" alt="boost.png (6897 bytes)" width="277" height="86">
|
||||
</td>
|
||||
<td align="middle">
|
||||
<h1>assert.hpp</h1>
|
||||
|
@@ -3,10 +3,9 @@
|
||||
//
|
||||
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
// 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/detail/lightweight_test.hpp>
|
||||
@@ -52,13 +51,18 @@ void test_disabled()
|
||||
|
||||
#define BOOST_ENABLE_ASSERT_HANDLER
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <cstdio>
|
||||
|
||||
int handler_invoked = 0;
|
||||
|
||||
void boost::assertion_failed(char const * expr, char const * function, char const * file, long line)
|
||||
{
|
||||
std::printf("Expression: %s\nFunction: %s\nFile: %s\nLine: %ld\n\n", expr, function, file, line);
|
||||
#if !defined(BOOST_NO_STDC_NAMESPACE)
|
||||
using std::printf;
|
||||
#endif
|
||||
|
||||
printf("Expression: %s\nFunction: %s\nFile: %s\nLine: %ld\n\n", expr, function, file, line);
|
||||
++handler_invoked;
|
||||
}
|
||||
|
||||
|
@@ -5,15 +5,14 @@
|
||||
</head>
|
||||
|
||||
<body bgcolor="white" link="blue" text="black" vlink="purple" alink="red">
|
||||
<h1><img src="../../c++boost.gif" alt="C++ Boost" align="middle"
|
||||
<h1><img src="../../boost.png" alt="C++ Boost" align="middle"
|
||||
width="277" height="86">Base-from-Member Idiom</h1>
|
||||
|
||||
<p>The class template <code>boost::base_from_member</code> provides
|
||||
a workaround for a class that needs to initialize a base class with a
|
||||
member. The class template is in <cite><a
|
||||
href="../../boost/utility/base_from_member.hpp">boost/utility/base_from_member.hpp</a></cite>
|
||||
which is included in <i><a href="../../boost/utility.hpp">boost/utility.hpp</a></i>.
|
||||
The class template is forward declared in <i><a href="../../boost/utility_fwd.hpp">boost/utility_fwd.hpp</a></i>.</p>
|
||||
which is included in <i><a href="../../boost/utility.hpp">boost/utility.hpp</a></i>.</p>
|
||||
|
||||
<p>There is test/example code in <cite><a
|
||||
href="base_from_member_test.cpp">base_from_member_test.cpp</a></cite>.</p>
|
||||
@@ -130,6 +129,10 @@ particular member type does not need to concern itself with the integer.</p>
|
||||
<h2><a name="synopsis">Synopsis</a></h2>
|
||||
|
||||
<blockquote><pre>
|
||||
#ifndef BOOST_BASE_FROM_MEMBER_MAX_ARITY
|
||||
#define BOOST_BASE_FROM_MEMBER_MAX_ARITY 10
|
||||
#endif
|
||||
|
||||
template < typename MemberType, int UniqueID = 0 >
|
||||
class boost::base_from_member
|
||||
{
|
||||
@@ -171,6 +174,14 @@ the template parameters of a templated constructor, make sure that
|
||||
the arguments are already close as possible to the actual type used in
|
||||
the data member's desired constructor.</p>
|
||||
|
||||
<p>The <var>BOOST_BASE_FROM_MEMBER_MAX_ARITY</var> macro constant specifies
|
||||
the maximum argument length for the constructor templates. The constant
|
||||
may be overridden if more (or less) argument configurations are needed. The
|
||||
constant may be read for code that is expandable like the class template and
|
||||
needs to maintain the same maximum size. (Example code would be a class that
|
||||
uses this class template as a base class for a member with a flexible set of
|
||||
constructors.)</p>
|
||||
|
||||
<h2><a name="usage">Usage</a></h2>
|
||||
|
||||
<p>With the starting example, the <code>fdoutbuf</code> sub-object needs
|
||||
@@ -337,6 +348,11 @@ with the exact pointer type used in <code>switcher</code>'s constructor.</p>
|
||||
<a href="http://www.informatik.uni-konstanz.de/~kuehl/c++/iostream/">IOStream
|
||||
example classes</a>.
|
||||
|
||||
<dt>Jonathan Turkanis
|
||||
<dd>Supplied an implementation of generating the constructor templates that
|
||||
can be controlled and automated with macros. The implementation uses
|
||||
the <a href="../preprocessor/index.html">Preprocessor library</a>.
|
||||
|
||||
<dt><a href="../../people/daryle_walker.html">Daryle Walker</a>
|
||||
<dd>Started the library. Contributed the test file <cite><a
|
||||
href="base_from_member_test.cpp">base_from_member_test.cpp</a></cite>.
|
||||
@@ -344,9 +360,9 @@ with the exact pointer type used in <code>switcher</code>'s constructor.</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<p>Revised: 14 June 2003</p>
|
||||
<p>Revised: 28 August 2004</p>
|
||||
|
||||
<p>Copyright 2001, 2003 Daryle Walker. Use, modification, and distribution
|
||||
<p>Copyright 2001, 2003, 2004 Daryle Walker. 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 a copy at <<a
|
||||
href="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</a>>.)</p>
|
||||
|
@@ -1,8 +1,7 @@
|
||||
// (C) Copyright David Abrahams 2000. Permission to copy, use, modify,
|
||||
// sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
// (C) Copyright David Abrahams 2000.
|
||||
// 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 <vector>
|
||||
#include <string>
|
||||
@@ -15,6 +14,7 @@
|
||||
#include <algorithm>
|
||||
#include <boost/detail/binary_search.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
#if defined(__SGI_STL_PORT) ? defined(__SGI_STL_OWN_IOSTREAMS) : (!defined(__GNUC__) || __GNUC__ > 2)
|
||||
# define USE_SSTREAM
|
||||
|
@@ -12,7 +12,7 @@ content="C:\PROGRAM FILES\MICROSOFT OFFICE\OFFICE\html.dot">
|
||||
<body bgcolor="#FFFFFF" text="#000000" link="#0000FF"
|
||||
vlink="#800080">
|
||||
|
||||
<h1><img src="../../c++boost.gif" width="276" height="86">Header
|
||||
<h1><img src="../../boost.png" width="276" height="86">Header
|
||||
<<a href="../../boost/detail/call_traits.hpp">boost/call_traits.hpp</a>></h1>
|
||||
|
||||
<p>All of the contents of <boost/call_traits.hpp> are
|
||||
|
@@ -19,7 +19,42 @@
|
||||
#include <typeinfo>
|
||||
#include <boost/call_traits.hpp>
|
||||
|
||||
#include <boost/type_traits/type_traits_test.hpp>
|
||||
#include <libs/type_traits/test/test.hpp>
|
||||
#include <libs/type_traits/test/check_type.hpp>
|
||||
|
||||
//
|
||||
// define tests here
|
||||
unsigned failures = 0;
|
||||
unsigned test_count = 0;
|
||||
//
|
||||
// This must get defined within the test file.
|
||||
// All compilers have bugs, set this to the number of
|
||||
// regressions *expected* from a given compiler,
|
||||
// if there are no workarounds for the bugs, *and*
|
||||
// the regressions have been investigated.
|
||||
//
|
||||
extern unsigned int expected_failures;
|
||||
//
|
||||
// proc check_result()
|
||||
// Checks that there were no regressions:
|
||||
//
|
||||
int check_result(int argc, char** argv)
|
||||
{
|
||||
std::cout << test_count << " tests completed, "
|
||||
<< failures << " failures found, "
|
||||
<< expected_failures << " failures expected from this compiler." << std::endl;
|
||||
if((argc == 2)
|
||||
&& (argv[1][0] == '-')
|
||||
&& (argv[1][1] == 'a')
|
||||
&& (argv[1][2] == 0))
|
||||
{
|
||||
std::cout << "Press any key to continue...";
|
||||
std::cin.get();
|
||||
}
|
||||
return (failures == expected_failures)
|
||||
? 0
|
||||
: (failures != 0) ? static_cast<int>(failures) : -1;
|
||||
}
|
||||
|
||||
// a way prevent warnings for unused variables
|
||||
template<class T> inline void unused_variable(const T&) {}
|
||||
@@ -231,51 +266,51 @@ int main(int argc, char *argv[ ])
|
||||
typedef int& r_type;
|
||||
typedef const r_type cr_type;
|
||||
|
||||
type_test(comparible_UDT, boost::call_traits<comparible_UDT>::value_type)
|
||||
type_test(comparible_UDT&, boost::call_traits<comparible_UDT>::reference)
|
||||
type_test(const comparible_UDT&, boost::call_traits<comparible_UDT>::const_reference)
|
||||
type_test(const comparible_UDT&, boost::call_traits<comparible_UDT>::param_type)
|
||||
type_test(int, boost::call_traits<int>::value_type)
|
||||
type_test(int&, boost::call_traits<int>::reference)
|
||||
type_test(const int&, boost::call_traits<int>::const_reference)
|
||||
type_test(const int, boost::call_traits<int>::param_type)
|
||||
type_test(int*, boost::call_traits<int*>::value_type)
|
||||
type_test(int*&, boost::call_traits<int*>::reference)
|
||||
type_test(int*const&, boost::call_traits<int*>::const_reference)
|
||||
type_test(int*const, boost::call_traits<int*>::param_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)
|
||||
type_test(int&, boost::call_traits<int&>::value_type)
|
||||
type_test(int&, boost::call_traits<int&>::reference)
|
||||
type_test(const int&, boost::call_traits<int&>::const_reference)
|
||||
type_test(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(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)))
|
||||
type_test(int&, boost::call_traits<cr_type>::value_type)
|
||||
type_test(int&, boost::call_traits<cr_type>::reference)
|
||||
type_test(const int&, boost::call_traits<cr_type>::const_reference)
|
||||
type_test(int&, boost::call_traits<cr_type>::param_type)
|
||||
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;
|
||||
failures += 4;
|
||||
test_count += 4;
|
||||
#endif
|
||||
type_test(const int&, boost::call_traits<const int&>::value_type)
|
||||
type_test(const int&, boost::call_traits<const int&>::reference)
|
||||
type_test(const int&, boost::call_traits<const int&>::const_reference)
|
||||
type_test(const int&, boost::call_traits<const int&>::param_type)
|
||||
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
|
||||
type_test(const int*, boost::call_traits<int[3]>::value_type)
|
||||
type_test(int(&)[3], boost::call_traits<int[3]>::reference)
|
||||
type_test(const int(&)[3], boost::call_traits<int[3]>::const_reference)
|
||||
type_test(const int*const, boost::call_traits<int[3]>::param_type)
|
||||
type_test(const int*, boost::call_traits<const int[3]>::value_type)
|
||||
type_test(const int(&)[3], boost::call_traits<const int[3]>::reference)
|
||||
type_test(const int(&)[3], boost::call_traits<const int[3]>::const_reference)
|
||||
type_test(const int*const, boost::call_traits<const int[3]>::param_type)
|
||||
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:
|
||||
type_test(test_abc1, boost::call_traits<test_abc1>::value_type)
|
||||
type_test(test_abc1&, boost::call_traits<test_abc1>::reference)
|
||||
type_test(const test_abc1&, boost::call_traits<test_abc1>::const_reference)
|
||||
type_test(const test_abc1&, boost::call_traits<test_abc1>::param_type)
|
||||
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;
|
||||
failures += 12;
|
||||
@@ -287,10 +322,10 @@ int main(int argc, char *argv[ ])
|
||||
test_count += 24;
|
||||
#endif
|
||||
// test with an incomplete type:
|
||||
type_test(incomplete_type, boost::call_traits<incomplete_type>::value_type)
|
||||
type_test(incomplete_type&, boost::call_traits<incomplete_type>::reference)
|
||||
type_test(const incomplete_type&, boost::call_traits<incomplete_type>::const_reference)
|
||||
type_test(const incomplete_type&, boost::call_traits<incomplete_type>::param_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);
|
||||
|
||||
return check_result(argc, argv);
|
||||
}
|
||||
@@ -410,7 +445,7 @@ template struct call_traits_test<int[2], true>;
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_MSVC) && _MSC_VER <= 1300
|
||||
unsigned int expected_failures = 14;
|
||||
unsigned int expected_failures = 12;
|
||||
#elif defined(__SUNPRO_CC)
|
||||
#if(__SUNPRO_CC <= 0x520)
|
||||
unsigned int expected_failures = 18;
|
||||
|
@@ -8,7 +8,7 @@
|
||||
<table border="0" width="100%">
|
||||
<tr>
|
||||
<td width="277">
|
||||
<img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" width="277" height="86">
|
||||
<img src="../../boost.png" alt="boost.png (6897 bytes)" width="277" height="86">
|
||||
</td>
|
||||
<td align="middle">
|
||||
<h1>checked_delete.hpp</h1>
|
||||
|
@@ -1,7 +1,8 @@
|
||||
// Boost checked_delete test program ---------------------------------------//
|
||||
|
||||
// Copyright Beman Dawes 2001.
|
||||
// See accompanying license for terms and conditions of use.
|
||||
// Copyright Beman Dawes 2001. 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.
|
||||
|
||||
|
@@ -1,30 +1,19 @@
|
||||
<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>Header </title>
|
||||
<boost/compressed_pair.hpp>
|
||||
</head>
|
||||
|
||||
<body bgcolor="#FFFFFF" text="#000000" link="#0000FF"
|
||||
vlink="#800080">
|
||||
|
||||
<h2><img src="../../c++boost.gif" width="276" height="86">Header
|
||||
<<a href="../../boost/detail/compressed_pair.hpp">boost/compressed_pair.hpp</a>></h2>
|
||||
|
||||
<p>All of the contents of <boost/compressed_pair.hpp> are
|
||||
defined inside namespace boost.</p>
|
||||
|
||||
<p>The class compressed pair is very similar to std::pair, but if
|
||||
either of the template arguments are empty classes, then the
|
||||
"empty base-class optimisation" is applied to compress
|
||||
the size of the pair.</p>
|
||||
|
||||
<pre>template <class T1, class T2>
|
||||
<head>
|
||||
<title>Header </title>
|
||||
<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">
|
||||
<boostcompressed_pair.hpp>
|
||||
</head>
|
||||
<body bgcolor="#ffffff" text="#000000" link="#0000ff" vlink="#800080">
|
||||
<h2><img src="../../boost.png" width="276" height="86">Header <<a href="../../boost/detail/compressed_pair.hpp">boost/compressed_pair.hpp</a>></h2>
|
||||
<p>All of the contents of <boost/compressed_pair.hpp> are defined inside
|
||||
namespace boost.</p>
|
||||
<p>The class compressed pair is very similar to std::pair, but if either of the
|
||||
template arguments are empty classes, then the "empty base-class optimisation"
|
||||
is applied to compress the size of the pair.</p>
|
||||
<pre>template <class T1, class T2>
|
||||
class compressed_pair
|
||||
{
|
||||
public:
|
||||
@@ -52,47 +41,35 @@ public:
|
||||
|
||||
void swap(compressed_pair& y);
|
||||
};</pre>
|
||||
|
||||
<p>The two members of the pair can be accessed using the member
|
||||
functions first() and second(). Note that not all member
|
||||
functions can be instantiated for all template parameter types.
|
||||
In particular compressed_pair can be instantiated for reference
|
||||
and array types, however in these cases the range of constructors
|
||||
that can be used are limited. If types T1 and T2 are the same
|
||||
type, then there is only one version of the single-argument
|
||||
constructor, and this constructor initialises both values in the
|
||||
pair to the passed value.</p>
|
||||
|
||||
<p>Note that compressed_pair can not be instantiated if either of
|
||||
the template arguments is a union type, unless there is compiler
|
||||
support for boost::is_union, or if boost::is_union is specialised
|
||||
for the union type.</p>
|
||||
|
||||
<p>Finally, a word of caution for Visual C++ 6 users: if either
|
||||
argument is an empty type, then assigning to that member will
|
||||
produce memory corruption, unless the empty type has a "do
|
||||
nothing" assignment operator defined. This is due to a bug
|
||||
in the way VC6 generates implicit assignment operators.</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<p>Revised 08 May 2001</p>
|
||||
|
||||
<p><EFBFBD> Copyright boost.org 2000. Permission to copy, use, modify,
|
||||
sell and distribute this document is granted provided this
|
||||
copyright notice appears in all copies. This document is provided
|
||||
"as is" without express or implied warranty, and with
|
||||
no claim as to its suitability for any purpose.</p>
|
||||
|
||||
<p>Based on contributions by Steve Cleary, Beman Dawes, Howard
|
||||
Hinnant and John Maddock.</p>
|
||||
|
||||
<p>Maintained by <a href="mailto:john@johnmaddock.co.uk">John
|
||||
Maddock</a>, the latest version of this file can be found at <a
|
||||
href="http://www.boost.org">www.boost.org</a>, and the boost
|
||||
discussion list at <a
|
||||
href="http://www.yahoogroups.com/list/boost">www.yahoogroups.com/list/boost</a>.</p>
|
||||
|
||||
<p> </p>
|
||||
</body>
|
||||
<p>The two members of the pair can be accessed using the member functions first()
|
||||
and second(). Note that not all member functions can be instantiated for all
|
||||
template parameter types. In particular compressed_pair can be instantiated for
|
||||
reference and array types, however in these cases the range of constructors
|
||||
that can be used are limited. If types T1 and T2 are the same type, then there
|
||||
is only one version of the single-argument constructor, and this constructor
|
||||
initialises both values in the pair to the passed value.</p>
|
||||
<P>Note that if either member is a POD type, then that member is not
|
||||
zero-initialized by the compressed_pair default constructor: it's up to you to
|
||||
supply an initial value for these types if you want them to have a default
|
||||
value.</P>
|
||||
<p>Note that compressed_pair can not be instantiated if either of the template
|
||||
arguments is a union type, unless there is compiler support for
|
||||
boost::is_union, or if boost::is_union is specialised for the union type.</p>
|
||||
<p>Finally, a word of caution for Visual C++ 6 users: if either argument is an
|
||||
empty type, then assigning to that member will produce memory corruption,
|
||||
unless the empty type has a "do nothing" assignment operator defined. This is
|
||||
due to a bug in the way VC6 generates implicit assignment operators.</p>
|
||||
<hr>
|
||||
<p>Revised 08 May 2001</p>
|
||||
<p><EFBFBD> Copyright boost.org 2000. Permission to copy, use, modify, sell and
|
||||
distribute this document is granted provided this copyright notice appears in
|
||||
all copies. This document is provided "as is" without express or implied
|
||||
warranty, and with no claim as to its suitability for any purpose.</p>
|
||||
<p>Based on contributions by Steve Cleary, Beman Dawes, Howard Hinnant and John
|
||||
Maddock.</p>
|
||||
<p>Maintained by <a href="mailto:john@johnmaddock.co.uk">John Maddock</a>, the
|
||||
latest version of this file can be found at <a href="http://www.boost.org">www.boost.org</a>,
|
||||
and the boost discussion list at <a href="http://www.yahoogroups.com/list/boost">www.yahoogroups.com/list/boost</a>.</p>
|
||||
<p> </p>
|
||||
</body>
|
||||
</html>
|
||||
|
@@ -14,29 +14,23 @@
|
||||
#include <cassert>
|
||||
|
||||
#include <boost/compressed_pair.hpp>
|
||||
#include <boost/type_traits/type_traits_test.hpp>
|
||||
#define BOOST_INCLUDE_MAIN
|
||||
#include <boost/test/test_tools.hpp>
|
||||
|
||||
using namespace boost;
|
||||
|
||||
namespace boost {
|
||||
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
|
||||
template <> struct is_empty<empty_UDT>
|
||||
{ static const bool value = true; };
|
||||
template <> struct is_empty<empty_POD_UDT>
|
||||
{ static const bool value = true; };
|
||||
template <> struct is_POD<empty_POD_UDT>
|
||||
{ static const bool value = true; };
|
||||
#else
|
||||
template <> struct is_empty<empty_UDT>
|
||||
{ enum{ value = true }; };
|
||||
template <> struct is_empty<empty_POD_UDT>
|
||||
{ enum{ value = true }; };
|
||||
template <> struct is_POD<empty_POD_UDT>
|
||||
{ enum{ value = true }; };
|
||||
#endif
|
||||
}
|
||||
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
|
||||
{
|
||||
@@ -85,47 +79,47 @@ void compressed_pair_tester<T1, T2>::test(first_param_type p1, second_param_type
|
||||
// first param construct:
|
||||
boost::compressed_pair<T1,T2> cp2(p1);
|
||||
cp2.second() = p2;
|
||||
BOOST_TEST(cp2.first() == p1);
|
||||
BOOST_TEST(cp2.second() == p2);
|
||||
BOOST_CHECK(cp2.first() == p1);
|
||||
BOOST_CHECK(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);
|
||||
BOOST_CHECK(cp3.second() == p2);
|
||||
BOOST_CHECK(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_CHECK(cp4.first() == p1);
|
||||
BOOST_CHECK(cp4.second() == p2);
|
||||
boost::compressed_pair<T1,T2> cp5(p3, p4);
|
||||
BOOST_TEST(cp5.first() == p3);
|
||||
BOOST_TEST(cp5.second() == p4);
|
||||
BOOST_CHECK(cp5.first() == p3);
|
||||
BOOST_CHECK(cp5.second() == p4);
|
||||
// check const members:
|
||||
const boost::compressed_pair<T1,T2>& cpr1 = cp4;
|
||||
BOOST_TEST(cpr1.first() == p1);
|
||||
BOOST_TEST(cpr1.second() == p2);
|
||||
BOOST_CHECK(cpr1.first() == p1);
|
||||
BOOST_CHECK(cpr1.second() == p2);
|
||||
|
||||
// copy construct:
|
||||
boost::compressed_pair<T1,T2> cp6(cp4);
|
||||
BOOST_TEST(cp6.first() == p1);
|
||||
BOOST_TEST(cp6.second() == p2);
|
||||
BOOST_CHECK(cp6.first() == p1);
|
||||
BOOST_CHECK(cp6.second() == p2);
|
||||
// assignment:
|
||||
cp1 = cp4;
|
||||
BOOST_TEST(cp1.first() == p1);
|
||||
BOOST_TEST(cp1.second() == p2);
|
||||
BOOST_CHECK(cp1.first() == p1);
|
||||
BOOST_CHECK(cp1.second() == p2);
|
||||
cp1 = cp5;
|
||||
BOOST_TEST(cp1.first() == p3);
|
||||
BOOST_TEST(cp1.second() == p4);
|
||||
BOOST_CHECK(cp1.first() == p3);
|
||||
BOOST_CHECK(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);
|
||||
BOOST_CHECK(cp4.first() == p3);
|
||||
BOOST_CHECK(cp4.second() == p4);
|
||||
BOOST_CHECK(cp5.first() == p1);
|
||||
BOOST_CHECK(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);
|
||||
BOOST_CHECK(cp4.first() == p1);
|
||||
BOOST_CHECK(cp4.second() == p2);
|
||||
BOOST_CHECK(cp5.first() == p3);
|
||||
BOOST_CHECK(cp5.second() == p4);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -154,20 +148,20 @@ void compressed_pair_reference_tester<T1, T2>::test(first_param_type p1, second_
|
||||
#endif
|
||||
// both param construct:
|
||||
boost::compressed_pair<T1,T2> cp4(p1, p2);
|
||||
BOOST_TEST(cp4.first() == p1);
|
||||
BOOST_TEST(cp4.second() == p2);
|
||||
BOOST_CHECK(cp4.first() == p1);
|
||||
BOOST_CHECK(cp4.second() == p2);
|
||||
boost::compressed_pair<T1,T2> cp5(p3, p4);
|
||||
BOOST_TEST(cp5.first() == p3);
|
||||
BOOST_TEST(cp5.second() == p4);
|
||||
BOOST_CHECK(cp5.first() == p3);
|
||||
BOOST_CHECK(cp5.second() == p4);
|
||||
// check const members:
|
||||
const boost::compressed_pair<T1,T2>& cpr1 = cp4;
|
||||
BOOST_TEST(cpr1.first() == p1);
|
||||
BOOST_TEST(cpr1.second() == p2);
|
||||
BOOST_CHECK(cpr1.first() == p1);
|
||||
BOOST_CHECK(cpr1.second() == p2);
|
||||
|
||||
// copy construct:
|
||||
boost::compressed_pair<T1,T2> cp6(cp4);
|
||||
BOOST_TEST(cp6.first() == p1);
|
||||
BOOST_TEST(cp6.second() == p2);
|
||||
BOOST_CHECK(cp6.first() == p1);
|
||||
BOOST_CHECK(cp6.second() == p2);
|
||||
// assignment:
|
||||
// VC6 bug:
|
||||
// When second() is an empty class, VC6 performs the
|
||||
@@ -180,8 +174,8 @@ void compressed_pair_reference_tester<T1, T2>::test(first_param_type p1, second_
|
||||
// settings - some generate the problem others do not.
|
||||
cp4.first() = p3;
|
||||
cp4.second() = p4;
|
||||
BOOST_TEST(cp4.first() == p3);
|
||||
BOOST_TEST(cp4.second() == p4);
|
||||
BOOST_CHECK(cp4.first() == p3);
|
||||
BOOST_CHECK(cp4.second() == p4);
|
||||
}
|
||||
//
|
||||
// supplimentary tests for case where first arg only is a reference type:
|
||||
@@ -205,8 +199,8 @@ void compressed_pair_reference1_tester<T1, T2>::test(first_param_type p1, second
|
||||
// first param construct:
|
||||
boost::compressed_pair<T1,T2> cp2(p1);
|
||||
cp2.second() = p2;
|
||||
BOOST_TEST(cp2.first() == p1);
|
||||
BOOST_TEST(cp2.second() == p2);
|
||||
BOOST_CHECK(cp2.first() == p1);
|
||||
BOOST_CHECK(cp2.second() == p2);
|
||||
#endif
|
||||
}
|
||||
//
|
||||
@@ -231,8 +225,8 @@ void compressed_pair_reference2_tester<T1, T2>::test(first_param_type p1, second
|
||||
// second param construct:
|
||||
boost::compressed_pair<T1,T2> cp3(p2);
|
||||
cp3.first() = p1;
|
||||
BOOST_TEST(cp3.second() == p2);
|
||||
BOOST_TEST(cp3.first() == p1);
|
||||
BOOST_CHECK(cp3.second() == p2);
|
||||
BOOST_CHECK(cp3.first() == p1);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -259,14 +253,14 @@ void compressed_pair_array1_tester<T1, T2>::test(first_param_type p1, second_par
|
||||
// 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]);
|
||||
BOOST_CHECK(cp3.second() == p2);
|
||||
BOOST_CHECK(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_CHECK(cpr1.first()[0] == p1[0]);
|
||||
BOOST_CHECK(cpr1.second() == p2);
|
||||
|
||||
BOOST_TEST(sizeof(T1) == sizeof(cp1.first()));
|
||||
BOOST_CHECK(sizeof(T1) == sizeof(cp1.first()));
|
||||
}
|
||||
|
||||
template <class T1, class T2>
|
||||
@@ -289,14 +283,14 @@ void compressed_pair_array2_tester<T1, T2>::test(first_param_type p1, second_par
|
||||
// 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]);
|
||||
BOOST_CHECK(cp2.first() == p1);
|
||||
BOOST_CHECK(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_CHECK(cpr1.first() == p1);
|
||||
BOOST_CHECK(cpr1.second()[0] == p2[0]);
|
||||
|
||||
BOOST_TEST(sizeof(T2) == sizeof(cp1.second()));
|
||||
BOOST_CHECK(sizeof(T2) == sizeof(cp1.second()));
|
||||
}
|
||||
|
||||
template <class T1, class T2>
|
||||
@@ -318,15 +312,15 @@ void compressed_pair_array_tester<T1, T2>::test(first_param_type p1, second_para
|
||||
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]);
|
||||
BOOST_CHECK(cp1.first()[0] == p1[0]);
|
||||
BOOST_CHECK(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_CHECK(cpr1.first()[0] == p1[0]);
|
||||
BOOST_CHECK(cpr1.second()[0] == p2[0]);
|
||||
|
||||
BOOST_TEST(sizeof(T1) == sizeof(cp1.first()));
|
||||
BOOST_TEST(sizeof(T2) == sizeof(cp1.second()));
|
||||
BOOST_CHECK(sizeof(T1) == sizeof(cp1.first()));
|
||||
BOOST_CHECK(sizeof(T2) == sizeof(cp1.second()));
|
||||
}
|
||||
|
||||
int test_main(int, char *[])
|
||||
|
@@ -1,325 +0,0 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
||||
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
|
||||
<meta name="ProgId" content="FrontPage.Editor.Document">
|
||||
<title>Counting Iterator Adaptor Documentation</title>
|
||||
</head>
|
||||
|
||||
<body bgcolor="#FFFFFF" text="#000000">
|
||||
|
||||
<img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)"
|
||||
align="center" width="277" height="86">
|
||||
|
||||
<h1>Counting Iterator Adaptor</h1>
|
||||
|
||||
Defined in header
|
||||
<a href="../../boost/counting_iterator.hpp">boost/counting_iterator.hpp</a>
|
||||
|
||||
<p>
|
||||
How would you fill up a vector with the numbers zero
|
||||
through one hundred using <a
|
||||
href="http://www.sgi.com/tech/stl/copy.html"><tt>std::copy()</tt></a>? The
|
||||
only iterator operation missing from builtin integer types is an
|
||||
<tt>operator*()</tt> that returns the current
|
||||
value of the integer. The counting iterator adaptor adds this crucial piece of
|
||||
functionality to whatever type it wraps. One can use the
|
||||
counting iterator adaptor not only with integer types, but with any
|
||||
type that is <tt>Incrementable</tt> (see type requirements <a href="#requirements">below</a>). The
|
||||
following <b>pseudo-code</b> shows the general idea of how the
|
||||
counting iterator is implemented.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
// inside a hypothetical counting_iterator class...
|
||||
typedef Incrementable value_type;
|
||||
value_type counting_iterator::operator*() const {
|
||||
return this->base; // no dereference!
|
||||
}
|
||||
</pre>
|
||||
|
||||
All of the other operators of the counting iterator behave in the same
|
||||
fashion as the <tt>Incrementable</tt> base type.
|
||||
|
||||
<h2>Synopsis</h2>
|
||||
|
||||
<pre>
|
||||
namespace boost {
|
||||
template <class Incrementable>
|
||||
struct <a href="#counting_iterator_traits">counting_iterator_traits</a>;
|
||||
|
||||
template <class Incrementable>
|
||||
struct <a href="#counting_iterator_generator">counting_iterator_generator</a>;
|
||||
|
||||
template <class Incrementable>
|
||||
typename counting_iterator_generator<Incrementable>::type
|
||||
<a href="#make_counting_iterator">make_counting_iterator</a>(Incrementable x);
|
||||
}
|
||||
</pre>
|
||||
|
||||
<hr>
|
||||
|
||||
<h2><a name="counting_iterator_generator">The Counting Iterator Type
|
||||
Generator</a></h2>
|
||||
|
||||
The class template <tt>counting_iterator_generator<Incrementable></tt> is a <a href="../../more/generic_programming.html#type_generator">type generator</a> for counting iterators.
|
||||
|
||||
<pre>
|
||||
template <class Incrementable>
|
||||
class counting_iterator_generator
|
||||
{
|
||||
public:
|
||||
typedef <a href="./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a><...> type;
|
||||
};
|
||||
</pre>
|
||||
|
||||
<h3>Example</h3>
|
||||
|
||||
In this example we use the counting iterator generator to create a
|
||||
counting iterator, and count from zero to four.
|
||||
|
||||
<pre>
|
||||
#include <boost/config.hpp>
|
||||
#include <iostream>
|
||||
#include <boost/counting_iterator.hpp>
|
||||
|
||||
int main(int, char*[])
|
||||
{
|
||||
// Example of using counting_iterator_generator
|
||||
std::cout << "counting from 0 to 4:" << std::endl;
|
||||
boost::counting_iterator_generator<int>::type first(0), last(4);
|
||||
std::copy(first, last, std::ostream_iterator<int>(std::cout, " "));
|
||||
std::cout << std::endl;
|
||||
|
||||
// to be continued...
|
||||
</pre>
|
||||
The output from this part is:
|
||||
<pre>
|
||||
counting from 0 to 4:
|
||||
0 1 2 3
|
||||
</pre>
|
||||
|
||||
<h3>Template Parameters</h3>
|
||||
|
||||
<Table border>
|
||||
<TR>
|
||||
<TH>Parameter</TH><TH>Description</TH>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><tt>Incrementable</tt></TD>
|
||||
<TD>The type being wrapped by the adaptor.</TD>
|
||||
</TR>
|
||||
|
||||
</Table>
|
||||
|
||||
<h3>Model of</h3>
|
||||
|
||||
If the <tt>Incrementable</tt> type has all of the functionality of a
|
||||
<a href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random
|
||||
Access Iterator</a> except the <tt>operator*()</tt>, then the counting
|
||||
iterator will be a model of <a
|
||||
href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random
|
||||
Access Iterator</a>. If the <tt>Incrementable</tt> type has less
|
||||
functionality, then the counting iterator will have correspondingly
|
||||
less functionality.
|
||||
|
||||
<h3><a name="requirements">Type Requirements</a></h3>
|
||||
|
||||
The <tt>Incrementable</tt> type must be <a
|
||||
href="http://www.sgi.com/tech/stl/DefaultConstructible.html">Default
|
||||
Constructible</a>, <a href="./CopyConstructible.html">Copy
|
||||
Constructible</a>, and <a href="./Assignable.html">Assignable</a>.
|
||||
Also, the <tt>Incrementable</tt> type must provide access to an
|
||||
associated <tt>difference_type</tt> and <tt>iterator_category</tt>
|
||||
through the <a
|
||||
href="#counting_iterator_traits"><tt>counting_iterator_traits</tt></a>
|
||||
class.
|
||||
|
||||
<p>
|
||||
Furthermore, if you wish to create a counting iterator that is a <a
|
||||
href="http://www.sgi.com/tech/stl/ForwardIterator.html"> Forward
|
||||
Iterator</a>, then the following expressions must be valid:
|
||||
<pre>
|
||||
Incrementable i, j;
|
||||
++i // pre-increment
|
||||
i == j // operator equal
|
||||
</pre>
|
||||
If you wish to create a counting iterator that is a <a
|
||||
href="http://www.sgi.com/tech/stl/BidirectionalIterator.html">
|
||||
Bidirectional Iterator</a>, then pre-decrement is also required:
|
||||
<pre>
|
||||
--i
|
||||
</pre>
|
||||
If you wish to create a counting iterator that is a <a
|
||||
href="http://www.sgi.com/tech/stl/RandomAccessIterator.html"> Random
|
||||
Access Iterator</a>, then these additional expressions are also required:
|
||||
<pre>
|
||||
<a href="#counting_iterator_traits">counting_iterator_traits</a><Incrementable>::difference_type n;
|
||||
i += n
|
||||
n = i - j
|
||||
i < j
|
||||
</pre>
|
||||
|
||||
|
||||
|
||||
<h3>Members</h3>
|
||||
|
||||
The counting iterator type implements the member functions and
|
||||
operators required of the <a
|
||||
href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random
|
||||
Access Iterator</a> concept. In addition it has the following
|
||||
constructor:
|
||||
|
||||
<pre>
|
||||
counting_iterator_generator::type(const Incrementable& i)
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
<hr>
|
||||
<p>
|
||||
|
||||
|
||||
<h2><a name="make_counting_iterator">The Counting Iterator Object Generator</a></h2>
|
||||
|
||||
<pre>
|
||||
template <class Incrementable>
|
||||
typename counting_iterator_generator<Incrementable>::type
|
||||
make_counting_iterator(Incrementable base);
|
||||
</pre>
|
||||
|
||||
An <a href="../../more/generic_programming.html#object_generator">object
|
||||
generator</a> function that provides a convenient way to create counting
|
||||
iterators.<p>
|
||||
|
||||
|
||||
|
||||
<h3>Example</h3>
|
||||
|
||||
In this example we count from negative five to positive five, this
|
||||
time using the <tt>make_counting_iterator()</tt> function to save some
|
||||
typing.
|
||||
|
||||
<pre>
|
||||
// continuing from previous example...
|
||||
|
||||
std::cout << "counting from -5 to 4:" << std::endl;
|
||||
std::copy(boost::make_counting_iterator(-5),
|
||||
boost::make_counting_iterator(5),
|
||||
std::ostream_iterator<int>(std::cout, " "));
|
||||
std::cout << std::endl;
|
||||
|
||||
// to be continued...
|
||||
</pre>
|
||||
The output from this part is:
|
||||
<pre>
|
||||
counting from -5 to 4:
|
||||
-5 -4 -3 -2 -1 0 1 2 3 4
|
||||
</pre>
|
||||
|
||||
In the next example we create an array of numbers, and then create a
|
||||
second array of pointers, where each pointer is the address of a
|
||||
number in the first array. The counting iterator makes it easy to do
|
||||
this since dereferencing a counting iterator that is wrapping an
|
||||
iterator over the array of numbers just returns a pointer to the
|
||||
current location in the array. We then use the <a
|
||||
href="./indirect_iterator.htm">indirect iterator adaptor</a> to print
|
||||
out the number in the array by accessing the numbers through the array
|
||||
of pointers.
|
||||
|
||||
<pre>
|
||||
// continuing from previous example...
|
||||
|
||||
const int N = 7;
|
||||
std::vector<int> numbers;
|
||||
// Fill "numbers" array with [0,N)
|
||||
std::copy(boost::make_counting_iterator(0), boost::make_counting_iterator(N),
|
||||
std::back_inserter(numbers));
|
||||
|
||||
std::vector<std::vector<int>::iterator> pointers;
|
||||
|
||||
// Use counting iterator to fill in the array of pointers.
|
||||
std::copy(boost::make_counting_iterator(numbers.begin()),
|
||||
boost::make_counting_iterator(numbers.end()),
|
||||
std::back_inserter(pointers));
|
||||
|
||||
// Use indirect iterator to print out numbers by accessing
|
||||
// them through the array of pointers.
|
||||
std::cout << "indirectly printing out the numbers from 0 to "
|
||||
<< N << std::endl;
|
||||
std::copy(boost::make_indirect_iterator(pointers.begin()),
|
||||
boost::make_indirect_iterator(pointers.end()),
|
||||
std::ostream_iterator<int>(std::cout, " "));
|
||||
std::cout << std::endl;
|
||||
</pre>
|
||||
The output is:
|
||||
<pre>
|
||||
indirectly printing out the numbers from 0 to 7
|
||||
0 1 2 3 4 5 6
|
||||
</pre>
|
||||
|
||||
<hr>
|
||||
|
||||
<h2><a name="counting_iterator_traits">Counting Iterator Traits</a></h2>
|
||||
|
||||
The counting iterator adaptor needs to determine the appropriate
|
||||
<tt>difference_type</tt> and <tt>iterator_category</tt> to use based on the
|
||||
<tt>Incrementable</tt> type supplied by the user. The
|
||||
<tt>counting_iterator_traits</tt> class provides these types. If the
|
||||
<tt>Incrementable</tt> type is an integral type or an iterator, these types
|
||||
will be correctly deduced by the <tt>counting_iterator_traits</tt> provided by
|
||||
the library. Otherwise, the user must specialize
|
||||
<tt>counting_iterator_traits</tt> for her type or add nested typedefs to
|
||||
her type to fulfill the needs of
|
||||
<a href="http://www.sgi.com/tech/stl/iterator_traits.html">
|
||||
<tt>std::iterator_traits</tt></a>.
|
||||
|
||||
<p>The following pseudocode describes how the <tt>counting_iterator_traits</tt> are determined:
|
||||
|
||||
<pre>
|
||||
template <class Incrementable>
|
||||
struct counting_iterator_traits
|
||||
{
|
||||
if (numeric_limits<Incrementable>::is_specialized) {
|
||||
if (!numeric_limits<Incrementable>::is_integer)
|
||||
COMPILE_TIME_ERROR;
|
||||
|
||||
if (!numeric_limits<Incrementable>::is_bounded
|
||||
&& numeric_limits<Incrementable>::is_signed) {
|
||||
typedef Incrementable difference_type;
|
||||
}
|
||||
else if (numeric_limits<Incrementable>::is_integral) {
|
||||
typedef <i>next-larger-signed-type-or-intmax_t</i> difference_type;
|
||||
}
|
||||
typedef std::random_access_iterator_tag iterator_category;
|
||||
} else {
|
||||
typedef std::iterator_traits<Incrementable>::difference_type difference_type;
|
||||
typedef std::iterator_traits<Incrementable>::iterator_category iterator_category;
|
||||
}
|
||||
};
|
||||
</pre>
|
||||
|
||||
<p>The italicized sections above are implementation details, but it is important
|
||||
to know that the <tt>difference_type</tt> for integral types is selected so that
|
||||
it can always represent the difference between two values if such a built-in
|
||||
integer exists. On platforms with a working <tt>std::numeric_limits</tt>
|
||||
implementation, the <tt>difference_type</tt> for any variable-length signed
|
||||
integer type <tt>T</tt> is <tt>T</tt> itself.
|
||||
|
||||
<hr>
|
||||
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->19 Aug 2001<!--webbot bot="Timestamp" endspan i-checksum="14767" --></p>
|
||||
<p><EFBFBD> Copyright Jeremy Siek 2000. Permission to copy, use,
|
||||
modify, sell and distribute this document is granted provided this copyright
|
||||
notice appears in all copies. This document is provided "as is"
|
||||
without express or implied warranty, and with no claim as to its suitability for
|
||||
any purpose.</p>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
<!-- LocalWords: html charset alt gif hpp incrementable const namespace htm
|
||||
-->
|
||||
<!-- LocalWords: struct typename iostream int Siek CopyConstructible pre
|
||||
-->
|
||||
|
@@ -1,60 +0,0 @@
|
||||
// (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
#include <boost/iterator/counting_iterator.hpp>
|
||||
#include <boost/iterator/indirect_iterator.hpp>
|
||||
|
||||
int main(int, char*[])
|
||||
{
|
||||
// Example of using counting_iterator_generator
|
||||
std::cout << "counting from 0 to 4:" << std::endl;
|
||||
boost::counting_iterator<int> first(0), last(4);
|
||||
std::copy(first, last, std::ostream_iterator<int>(std::cout, " "));
|
||||
std::cout << std::endl;
|
||||
|
||||
// Example of using make_counting_iterator()
|
||||
std::cout << "counting from -5 to 4:" << std::endl;
|
||||
std::copy(boost::make_counting_iterator(-5),
|
||||
boost::make_counting_iterator(5),
|
||||
std::ostream_iterator<int>(std::cout, " "));
|
||||
std::cout << std::endl;
|
||||
|
||||
// Example of using counting iterator to create an array of pointers.
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||
const
|
||||
#endif
|
||||
int N = 7;
|
||||
std::vector<int> numbers;
|
||||
// Fill "numbers" array with [0,N)
|
||||
std::copy(
|
||||
boost::make_counting_iterator(0)
|
||||
, boost::make_counting_iterator(N)
|
||||
, std::back_inserter(numbers));
|
||||
|
||||
std::vector<std::vector<int>::iterator> pointers;
|
||||
|
||||
// Use counting iterator to fill in the array of pointers.
|
||||
// causes an ICE with MSVC6
|
||||
std::copy(boost::make_counting_iterator(numbers.begin()),
|
||||
boost::make_counting_iterator(numbers.end()),
|
||||
std::back_inserter(pointers));
|
||||
|
||||
// Use indirect iterator to print out numbers by accessing
|
||||
// them through the array of pointers.
|
||||
std::cout << "indirectly printing out the numbers from 0 to "
|
||||
<< N << std::endl;
|
||||
std::copy(boost::make_indirect_iterator(pointers.begin()),
|
||||
boost::make_indirect_iterator(pointers.end()),
|
||||
std::ostream_iterator<int>(std::cout, " "));
|
||||
std::cout << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
@@ -8,7 +8,7 @@
|
||||
<table border="0" width="100%">
|
||||
<tr>
|
||||
<td width="277">
|
||||
<img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" width="277" height="86">
|
||||
<img src="../../boost.png" alt="boost.png (6897 bytes)" width="277" height="86">
|
||||
</td>
|
||||
<td align="middle">
|
||||
<h1>current_function.hpp</h1>
|
||||
|
@@ -12,18 +12,22 @@
|
||||
//
|
||||
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
// 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/current_function.hpp>
|
||||
#include <boost/config.hpp>
|
||||
#include <cstdio>
|
||||
|
||||
void message(char const * file, long line, char const * func, char const * msg)
|
||||
{
|
||||
std::printf("%s(%ld): %s in function '%s'\n", file, line, msg, func);
|
||||
#if !defined(BOOST_NO_STDC_NAMESPACE)
|
||||
using std::printf;
|
||||
#endif
|
||||
|
||||
printf("%s(%ld): %s in function '%s'\n", file, line, msg, func);
|
||||
}
|
||||
|
||||
#define MESSAGE(msg) message(__FILE__, __LINE__, BOOST_CURRENT_FUNCTION, msg)
|
||||
@@ -31,4 +35,6 @@ void message(char const * file, long line, char const * func, char const * msg)
|
||||
int main()
|
||||
{
|
||||
MESSAGE("assertion failed");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@@ -17,7 +17,7 @@
|
||||
|
||||
|
||||
<h1>
|
||||
<img border="0" src="../../c++boost.gif" align="center" width="277" height="86">enable_if</h1>
|
||||
<img border="0" src="../../boost.png" align="center" width="277" height="86">enable_if</h1>
|
||||
<BR>
|
||||
<BR>
|
||||
Copyright 2003 Jaakko Järvi, Jeremiah Willcock, Andrew Lumsdaine.<BR>
|
||||
@@ -128,7 +128,7 @@ When valid, <TT>enable_if_c<B, T>::type</TT> equals <TT>T</TT>.
|
||||
The <TT>enable_if_c</TT> template can thus be used for controlling when functions are considered for
|
||||
overload resolution and when they are not.
|
||||
For example, the following function is defined for all arithmetic types (according to the
|
||||
classification of the <A HREF="http://www.boost.org/libs/type_traits">Boost type_traits library</A>):
|
||||
classification of the <A HREF="../type_traits/index.html">Boost type_traits library</A>):
|
||||
<PRE>template <class T>
|
||||
typename enable_if_c<boost::is_arithmetic<T>::value, T>::type
|
||||
foo(T t) { return t; }
|
||||
@@ -303,7 +303,7 @@ foo(T t);
|
||||
<UL><LI>
|
||||
Use an extra dummy parameter which disambiguates the functions. Use a default value for
|
||||
it to hide the parameter from the caller. For example:
|
||||
<PRE>template <class T> struct dummy { dummy(int) {} };
|
||||
<PRE>template <int> struct dummy { dummy(int) {} };
|
||||
|
||||
template <class T>
|
||||
typename enable_if<boost::is_arithmetic<T>, T>::type
|
||||
|
33
enable_if/test/Jamfile
Normal file
33
enable_if/test/Jamfile
Normal file
@@ -0,0 +1,33 @@
|
||||
# Copyright David Abrahams 2003.
|
||||
# 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/
|
||||
|
||||
subproject libs/utility/enable_if/test ;
|
||||
|
||||
# bring in rules for testing
|
||||
import testing ;
|
||||
|
||||
# Make tests run by default.
|
||||
DEPENDS all : test ;
|
||||
|
||||
{
|
||||
local test_monitor = <lib>@boost/libs/test/build/boost_test_exec_monitor ;
|
||||
|
||||
# look in BOOST_ROOT for sources first, just in this Jamfile
|
||||
local SEARCH_SOURCE = $(BOOST_ROOT) $(SEARCH_SOURCE) ;
|
||||
|
||||
test-suite utility/enable_if
|
||||
:
|
||||
[ run libs/utility/enable_if/test/constructors.cpp $(test_monitor) ]
|
||||
[ run libs/utility/enable_if/test/dummy_arg_disambiguation.cpp $(test_monitor) ]
|
||||
[ run libs/utility/enable_if/test/lazy.cpp $(test_monitor) ]
|
||||
[ run libs/utility/enable_if/test/lazy_test.cpp $(test_monitor) ]
|
||||
[ run libs/utility/enable_if/test/member_templates.cpp $(test_monitor) ]
|
||||
[ run libs/utility/enable_if/test/namespace_disambiguation.cpp $(test_monitor) ]
|
||||
[ run libs/utility/enable_if/test/no_disambiguation.cpp $(test_monitor) ]
|
||||
[ run libs/utility/enable_if/test/partial_specializations.cpp $(test_monitor) ]
|
||||
;
|
||||
}
|
23
enable_if/test/Jamfile.v2
Normal file
23
enable_if/test/Jamfile.v2
Normal file
@@ -0,0 +1,23 @@
|
||||
# Copyright David Abrahams 2003.
|
||||
# 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/
|
||||
|
||||
project
|
||||
: requirements <library>/boost/test//boost_test_exec_monitor
|
||||
;
|
||||
|
||||
test-suite utility/enable_if
|
||||
:
|
||||
[ run constructors.cpp ]
|
||||
[ run dummy_arg_disambiguation.cpp ]
|
||||
[ run lazy.cpp ]
|
||||
[ run lazy_test.cpp ]
|
||||
[ run member_templates.cpp ]
|
||||
[ run namespace_disambiguation.cpp ]
|
||||
[ run no_disambiguation.cpp ]
|
||||
[ run partial_specializations.cpp ]
|
||||
;
|
||||
|
@@ -1,273 +0,0 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
||||
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
|
||||
<meta name="ProgId" content="FrontPage.Editor.Document">
|
||||
<title>Filter Iterator Adaptor Documentation</title>
|
||||
</head>
|
||||
|
||||
<body bgcolor="#FFFFFF" text="#000000">
|
||||
|
||||
<img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)"
|
||||
align="center" width="277" height="86">
|
||||
|
||||
<h1>Filter Iterator Adaptor</h1>
|
||||
|
||||
Defined in header
|
||||
<a href="../../boost/iterator_adaptors.hpp">boost/iterator_adaptors.hpp</a>
|
||||
|
||||
|
||||
<p>
|
||||
The filter iterator adaptor creates a view of an iterator range in
|
||||
which some elements of the range are skipped over. A <a
|
||||
href="http://www.sgi.com/tech/stl/Predicate.html">Predicate</a>
|
||||
function object controls which elements are skipped. When the
|
||||
predicate is applied to an element, if it returns <tt>true</tt> then
|
||||
the element is retained and if it returns <tt>false</tt> then the
|
||||
element is skipped over.
|
||||
|
||||
|
||||
<h2>Synopsis</h2>
|
||||
|
||||
<pre>
|
||||
namespace boost {
|
||||
template <class Predicate, class BaseIterator, ...>
|
||||
class filter_iterator_generator;
|
||||
|
||||
template <class Predicate, class BaseIterator>
|
||||
typename filter_iterator_generator<Predicate, BaseIterator>::type
|
||||
make_filter_iterator(BaseIterator first, BaseIterator last, const Predicate& p = Predicate());
|
||||
}
|
||||
</pre>
|
||||
|
||||
<hr>
|
||||
|
||||
<h2><a name="filter_iterator_generator">The Filter Iterator Type
|
||||
Generator</a></h2>
|
||||
|
||||
The class <tt>filter_iterator_generator</tt> is a helper class whose
|
||||
purpose is to construct a filter iterator type. The template
|
||||
parameters for this class are the <tt>Predicate</tt> function object
|
||||
type and the <tt>BaseIterator</tt> type that is being wrapped. In
|
||||
most cases the associated types for the wrapped iterator can be
|
||||
deduced from <tt>std::iterator_traits</tt>, but in some situations the
|
||||
user may want to override these types, so there are also template
|
||||
parameters for each of the iterator's associated types.
|
||||
|
||||
<pre>
|
||||
template <class Predicate, class BaseIterator,
|
||||
class Value, class Reference, class Pointer, class Category, class Distance>
|
||||
class filter_iterator_generator
|
||||
{
|
||||
public:
|
||||
typedef <tt><a href="./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a><...></tt> type; // the resulting filter iterator type
|
||||
}
|
||||
</pre>
|
||||
|
||||
|
||||
<h3>Example</h3>
|
||||
|
||||
The following example uses filter iterator to print out all the
|
||||
positive integers in an array.
|
||||
|
||||
<pre>
|
||||
struct is_positive_number {
|
||||
bool operator()(int x) { return 0 < x; }
|
||||
};
|
||||
int main() {
|
||||
int numbers[] = { 0, -1, 4, -3, 5, 8, -2 };
|
||||
const int N = sizeof(numbers)/sizeof(int);
|
||||
|
||||
typedef boost::filter_iterator_generator<is_positive_number, int*, int>::type FilterIter;
|
||||
is_positive_number predicate;
|
||||
FilterIter::policies_type policies(predicate, numbers + N);
|
||||
FilterIter filter_iter_first(numbers, policies);
|
||||
FilterIter filter_iter_last(numbers + N, policies);
|
||||
|
||||
std::copy(filter_iter_first, filter_iter_last, std::ostream_iterator<int>(std::cout, " "));
|
||||
std::cout << std::endl;
|
||||
return 0;
|
||||
}
|
||||
</pre>
|
||||
The output is:
|
||||
<pre>
|
||||
4 5 8
|
||||
</pre>
|
||||
|
||||
|
||||
<h3>Template Parameters</h3>
|
||||
|
||||
<Table border>
|
||||
<TR>
|
||||
<TH>Parameter</TH><TH>Description</TH>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><a href="http://www.sgi.com/tech/stl/Predicate.html"><tt>Predicate</tt></a></TD>
|
||||
<TD>The function object that determines which elements are retained and which elements are skipped.
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><tt>BaseIterator</tt></TD>
|
||||
<TD>The iterator type being wrapped. This type must at least be a model
|
||||
of the <a href="http://www.sgi.com/tech/stl/InputIterator">InputIterator</a> concept.</TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><tt>Value</tt></TD>
|
||||
<TD>The <tt>value_type</tt> of the resulting iterator,
|
||||
unless const. If const, a conforming compiler strips constness for the
|
||||
<tt>value_type</tt>. Typically the default for this parameter is the
|
||||
appropriate type<a href="#1">[1]</a>.<br> <b>Default:</b>
|
||||
<tt>std::iterator_traits<BaseIterator>::value_type</TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><tt>Reference</tt></TD>
|
||||
<TD>The <tt>reference</tt> type of the resulting iterator, and in
|
||||
particular, the result type of <tt>operator*()</tt>. Typically the default for
|
||||
this parameter is the appropriate type.<br> <b>Default:</b> If
|
||||
<tt>Value</tt> is supplied, <tt>Value&</tt> is used. Otherwise
|
||||
<tt>std::iterator_traits<BaseIterator>::reference</tt> is
|
||||
used.</TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><tt>Pointer</tt></TD>
|
||||
<TD>The <tt>pointer</tt> type of the resulting iterator, and in
|
||||
particular, the result type of <tt>operator->()</tt>.
|
||||
Typically the default for
|
||||
this parameter is the appropriate type.<br>
|
||||
<b>Default:</b> If <tt>Value</tt> was supplied, then <tt>Value*</tt>,
|
||||
otherwise <tt>std::iterator_traits<BaseIterator>::pointer</tt>.</TD>
|
||||
</TR>
|
||||
|
||||
|
||||
<TR>
|
||||
<TD><tt>Category</tt></TD>
|
||||
<TD>The <tt>iterator_category</tt> type for the resulting iterator.
|
||||
Typically the
|
||||
default for this parameter is the appropriate type. If you override
|
||||
this parameter, do not use <tt>bidirectional_iterator_tag</tt>
|
||||
because filter iterators can not go in reverse.<br>
|
||||
<b>Default:</b> <tt>std::iterator_traits<BaseIterator>::iterator_category</tt></TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><tt>Distance</tt></TD>
|
||||
<TD>The <tt>difference_type</tt> for the resulting iterator. Typically the default for
|
||||
this parameter is the appropriate type.<br>
|
||||
<b>Default:</b> <tt>std::iterator_traits<BaseIterator>::difference_type</TD>
|
||||
</TR>
|
||||
|
||||
</table>
|
||||
|
||||
|
||||
<h3>Model of</h3>
|
||||
|
||||
The filter iterator adaptor (the type
|
||||
<tt>filter_iterator_generator<...>::type</tt>) may be a model of <a
|
||||
href="http://www.sgi.com/tech/stl/InputIterator.html">InputIterator</a> or <a
|
||||
href="http://www.sgi.com/tech/stl/ForwardIterator.html">ForwardIterator</a>
|
||||
depending on the adapted iterator type.
|
||||
|
||||
|
||||
<h3>Members</h3>
|
||||
|
||||
The filter iterator type implements all of the member functions and
|
||||
operators required of the <a
|
||||
href="http://www.sgi.com/tech/stl/ForwardIterator.html">ForwardIterator</a>
|
||||
concept. In addition it has the following constructor:
|
||||
|
||||
<pre>filter_iterator_generator::type(const BaseIterator& it, const Policies& p = Policies())</pre>
|
||||
|
||||
<p>
|
||||
The policies type has only one public function, which is its constructor:
|
||||
|
||||
<pre>filter_iterator_generator::policies_type(const Predicate& p, const BaseIterator& end)</pre>
|
||||
|
||||
<p>
|
||||
<hr>
|
||||
<p>
|
||||
|
||||
<h2><a name="make_filter_iterator">The Make Filter Iterator Function</a></h2>
|
||||
|
||||
<pre>
|
||||
template <class Predicate, class BaseIterator>
|
||||
typename filter_generator<Predicate, BaseIterator>::type
|
||||
make_filter_iterator(BaseIterator first, BaseIterator last, const Predicate& p = Predicate())
|
||||
</pre>
|
||||
|
||||
This function provides a convenient way to create filter iterators.
|
||||
|
||||
<h3>Example</h3>
|
||||
|
||||
In this example we print out all numbers in the array that are
|
||||
greater than negative two.
|
||||
|
||||
<pre>
|
||||
int main()
|
||||
{
|
||||
int numbers[] = { 0, -1, 4, -3, 5, 8, -2 };
|
||||
const int N = sizeof(numbers)/sizeof(int);
|
||||
|
||||
std::copy(boost::make_filter_iterator(numbers, numbers + N,
|
||||
std::bind2nd(std::greater<int>(), -2)),
|
||||
boost::make_filter_iterator(numbers + N, numbers + N,
|
||||
std::bind2nd(std::greater<int>(), -2)),
|
||||
std::ostream_iterator<int>(std::cout, " "));
|
||||
std::cout << std::endl;
|
||||
|
||||
}
|
||||
</pre>
|
||||
The output is:
|
||||
<pre>
|
||||
0 -1 4 5 8
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
In the next example we print the positive numbers using the
|
||||
<tt>make_filter_iterator()</tt> function.
|
||||
|
||||
<pre>
|
||||
struct is_positive_number {
|
||||
bool operator()(int x) { return 0 < x; }
|
||||
};
|
||||
int main()
|
||||
{
|
||||
int numbers[] = { 0, -1, 4, -3, 5, 8, -2 };
|
||||
const int N = sizeof(numbers)/sizeof(int);
|
||||
|
||||
std::copy(boost::make_filter_iterator<is_positive_number>(numbers, numbers + N),
|
||||
boost::make_filter_iterator<is_positive_number>(numbers + N, numbers + N),
|
||||
std::ostream_iterator<int>(std::cout, " "));
|
||||
std::cout << std::endl;
|
||||
return 0;
|
||||
}
|
||||
</pre>
|
||||
The output is:
|
||||
<pre>
|
||||
4 5 8
|
||||
</pre>
|
||||
|
||||
|
||||
<h3>Notes</h3>
|
||||
|
||||
<a name="1">[1]</a> If the compiler does not support partial
|
||||
specialization and the wrapped iterator type is a builtin pointer then
|
||||
the <tt>Value</tt> type must be explicitly specified (don't use the
|
||||
default).
|
||||
|
||||
|
||||
<hr>
|
||||
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->09 Mar 2001<!--webbot bot="Timestamp" endspan i-checksum="14894" --></p>
|
||||
<p><EFBFBD> Copyright Jeremy Siek 2000. Permission to copy, use,
|
||||
modify, sell and distribute this document is granted provided this copyright
|
||||
notice appears in all copies. This document is provided "as is"
|
||||
without express or implied warranty, and with no claim as to its suitability for
|
||||
any purpose.</p>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
@@ -1,62 +0,0 @@
|
||||
// Example of using the filter iterator adaptor from
|
||||
// boost/iterator_adaptors.hpp.
|
||||
|
||||
// (C) Copyright Jeremy Siek 1999. Permission to copy, use, modify,
|
||||
// sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <boost/iterator/filter_iterator.hpp>
|
||||
|
||||
struct is_positive_number {
|
||||
bool operator()(int x) { return 0 < x; }
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
int numbers_[] = { 0, -1, 4, -3, 5, 8, -2 };
|
||||
const int N = sizeof(numbers_)/sizeof(int);
|
||||
|
||||
typedef int* base_iterator;
|
||||
base_iterator numbers(numbers_);
|
||||
|
||||
// Example using make_filter_iterator()
|
||||
std::copy(boost::make_filter_iterator<is_positive_number>(numbers, numbers + N),
|
||||
boost::make_filter_iterator<is_positive_number>(numbers + N, numbers + N),
|
||||
std::ostream_iterator<int>(std::cout, " "));
|
||||
std::cout << std::endl;
|
||||
|
||||
// Example using filter_iterator
|
||||
typedef boost::filter_iterator<is_positive_number, base_iterator>
|
||||
FilterIter;
|
||||
|
||||
is_positive_number predicate;
|
||||
FilterIter filter_iter_first(predicate, numbers, numbers + N);
|
||||
FilterIter filter_iter_last(predicate, numbers + N, numbers + N);
|
||||
|
||||
std::copy(filter_iter_first, filter_iter_last, std::ostream_iterator<int>(std::cout, " "));
|
||||
std::cout << std::endl;
|
||||
|
||||
// Another example using make_filter_iterator()
|
||||
std::copy(
|
||||
boost::make_filter_iterator(
|
||||
std::bind2nd(std::greater<int>(), -2)
|
||||
, numbers, numbers + N)
|
||||
|
||||
, boost::make_filter_iterator(
|
||||
std::bind2nd(std::greater<int>(), -2)
|
||||
, numbers + N, numbers + N)
|
||||
|
||||
, std::ostream_iterator<int>(std::cout, " ")
|
||||
);
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
@@ -1,47 +0,0 @@
|
||||
// (C) Copyright Jeremy Siek 2001. Permission to copy, use, modify,
|
||||
// sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
|
||||
// Revision History:
|
||||
|
||||
// 27 Feb 2001 Jeremy Siek
|
||||
// Initial checkin.
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/function_output_iterator.hpp>
|
||||
|
||||
struct string_appender
|
||||
{
|
||||
string_appender(std::string& s)
|
||||
: m_str(&s)
|
||||
{}
|
||||
|
||||
void operator()(const std::string& x) const
|
||||
{
|
||||
*m_str += x;
|
||||
}
|
||||
|
||||
std::string* m_str;
|
||||
};
|
||||
|
||||
int main(int, char*[])
|
||||
{
|
||||
std::vector<std::string> x;
|
||||
x.push_back("hello");
|
||||
x.push_back(" ");
|
||||
x.push_back("world");
|
||||
x.push_back("!");
|
||||
|
||||
std::string s = "";
|
||||
std::copy(x.begin(), x.end(),
|
||||
boost::make_function_output_iterator(string_appender(s)));
|
||||
|
||||
std::cout << s << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
@@ -1,169 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta name="generator" content="HTML Tidy, see www.w3.org">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
||||
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
|
||||
<meta name="ProgId" content="FrontPage.Editor.Document">
|
||||
|
||||
<title>Function Output Iterator Adaptor Documentation</title>
|
||||
</head>
|
||||
|
||||
<body bgcolor="#FFFFFF" text="#000000">
|
||||
|
||||
<img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align=
|
||||
"center" width="277" height="86">
|
||||
|
||||
<h1>Function Output Iterator Adaptor</h1>
|
||||
Defined in header <a href=
|
||||
"../../boost/function_output_iterator.hpp">boost/function_output_iterator.hpp</a>
|
||||
|
||||
<p>The function output iterator adaptor makes it easier to create
|
||||
custom output iterators. The adaptor takes a <a
|
||||
href="http://www.sgi.com/tech/stl/UnaryFunction.html">Unary
|
||||
Function</a> and creates a model of <a
|
||||
href="http://www.sgi.com/tech/stl/OutputIterator.html">Output
|
||||
Iterator</a>. Each item assigned to the output iterator is passed
|
||||
as an argument to the unary function. The motivation for this
|
||||
iterator is that creating a C++ Standard conforming output
|
||||
iterator is non-trivial, particularly because the proper
|
||||
implementation usually requires a proxy object. On the other hand,
|
||||
creating a function (or function object) is much simpler.
|
||||
|
||||
<h2>Synopsis</h2>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
namespace boost {
|
||||
template <class UnaryFunction>
|
||||
class function_output_iterator;
|
||||
|
||||
template <class UnaryFunction>
|
||||
function_output_iterator<UnaryFunction>
|
||||
make_function_output_iterator(const UnaryFunction& f = UnaryFunction())
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<h3>Example</h3>
|
||||
|
||||
In this example we create an output iterator that appends
|
||||
each item onto the end of a string, using the <tt>string_appender</tt>
|
||||
function.
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/function_output_iterator.hpp>
|
||||
|
||||
struct string_appender {
|
||||
string_appender(std::string& s) : m_str(s) { }
|
||||
void operator()(const std::string& x) const {
|
||||
m_str += x;
|
||||
}
|
||||
std::string& m_str;
|
||||
};
|
||||
|
||||
int main(int, char*[])
|
||||
{
|
||||
std::vector<std::string> x;
|
||||
x.push_back("hello");
|
||||
x.push_back(" ");
|
||||
x.push_back("world");
|
||||
x.push_back("!");
|
||||
|
||||
std::string s = "";
|
||||
std::copy(x.begin(), x.end(),
|
||||
boost::make_function_output_iterator(string_appender(s)));
|
||||
|
||||
std::cout << s << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<hr>
|
||||
|
||||
<h2><a name="function_output_iterator">The Function Output Iterator Class</a></h2>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
template <class UnaryFunction>
|
||||
class function_output_iterator;
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
The <tt>function_output_iterator</tt> class creates an <a
|
||||
href="http://www.sgi.com/tech/stl/OutputIterator.html">Output
|
||||
Iterator</a> out of a
|
||||
<a href="http://www.sgi.com/tech/stl/UnaryFunction.html">Unary
|
||||
Function</a>. Each item assigned to the output iterator is passed
|
||||
as an argument to the unary function.
|
||||
|
||||
<h3>Template Parameters</h3>
|
||||
|
||||
<table border>
|
||||
<tr>
|
||||
<th>Parameter
|
||||
|
||||
<th>Description
|
||||
|
||||
<tr>
|
||||
<td><tt>UnaryFunction</tt>
|
||||
|
||||
<td>The function type being wrapped. The return type of the
|
||||
function is not used, so it can be <tt>void</tt>. The
|
||||
function must be a model of <a
|
||||
href="http://www.sgi.com/tech/stl/UnaryFunction.html">Unary
|
||||
Function</a>.</td>
|
||||
</table>
|
||||
|
||||
<h3>Concept Model</h3>
|
||||
The function output iterator class is a model of <a
|
||||
href="http://www.sgi.com/tech/stl/OutputIterator.html">Output
|
||||
Iterator</a>.
|
||||
|
||||
<h2>Members</h3>
|
||||
The function output iterator implements the member functions
|
||||
and operators required of the <a
|
||||
href="http://www.sgi.com/tech/stl/OutputIterator.html">Output
|
||||
Iterator</a> concept. In addition it has the following constructor:
|
||||
<pre>
|
||||
explicit function_output_iterator(const UnaryFunction& f = UnaryFunction())
|
||||
</pre>
|
||||
<br>
|
||||
<br>
|
||||
|
||||
<hr>
|
||||
<h2><a name="make_function_output_iterator">The Function Output Iterator Object
|
||||
Generator</a></h2>
|
||||
|
||||
The <tt>make_function_output_iterator()</tt> function provides a
|
||||
more convenient way to create function output iterator objects. The
|
||||
function saves the user the trouble of explicitly writing out the
|
||||
iterator types. If the default argument is used, the function
|
||||
type must be provided as an explicit template argument.
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
template <class UnaryFunction>
|
||||
function_output_iterator<UnaryFunction>
|
||||
make_function_output_iterator(const UnaryFunction& f = UnaryFunction())
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<hr>
|
||||
|
||||
<p>© Copyright Jeremy Siek 2001. Permission to copy, use,
|
||||
modify, sell and distribute this document is granted provided this
|
||||
copyright notice appears in all copies. This document is provided
|
||||
"as is" without express or implied warranty, and with no claim as
|
||||
to its suitability for any purpose.
|
||||
|
||||
</body>
|
||||
</html>
|
@@ -7,7 +7,7 @@
|
||||
|
||||
<body bgcolor="#FFFFFF" text="#000000">
|
||||
|
||||
<img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align="center" width="277" height="86">
|
||||
<img src="../../boost.png" alt="boost.png (6897 bytes)" align="center" width="277" height="86">
|
||||
|
||||
<h1>Generator Iterator Adaptor</h1>
|
||||
Defined in header <a href="../../boost/generator_iterator.hpp">boost/generator_iterator.hpp</a>
|
||||
@@ -58,7 +58,7 @@ template <class Generator>
|
||||
class generator_iterator_generator
|
||||
{
|
||||
public:
|
||||
typedef <a href="iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a><...> type; // the resulting generator iterator type
|
||||
typedef <i>unspecified</i> type; // the resulting generator iterator type
|
||||
}
|
||||
</pre>
|
||||
|
||||
|
@@ -1,366 +0,0 @@
|
||||
// (C) Copyright David Abrahams 2001. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears in
|
||||
// all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// See http://www.boost.org for most recent version including documentation.
|
||||
//
|
||||
// Revision History
|
||||
// 11 Feb 2001 Compile with Borland, re-enable failing tests (David Abrahams)
|
||||
// 29 Jan 2001 Initial revision (David Abrahams)
|
||||
|
||||
#include <boost/half_open_range.hpp>
|
||||
#include <boost/utility.hpp>
|
||||
#include <iterator>
|
||||
#include <stdlib.h>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <cassert>
|
||||
#include <stdexcept>
|
||||
#ifndef BOOST_NO_LIMITS
|
||||
# include <limits>
|
||||
#endif
|
||||
#ifndef BOOST_NO_SLIST
|
||||
# include <slist>
|
||||
#endif
|
||||
|
||||
inline unsigned unsigned_random(unsigned max)
|
||||
{
|
||||
return (max > 0) ? (unsigned)rand() % max : 0;
|
||||
}
|
||||
|
||||
// Special tests for ranges supporting random access
|
||||
template <class T>
|
||||
void category_test_1(
|
||||
const boost::half_open_range<T>& r, std::random_access_iterator_tag)
|
||||
{
|
||||
typedef boost::half_open_range<T> range;
|
||||
typedef typename range::size_type size_type;
|
||||
size_type size = r.size();
|
||||
|
||||
// pick a random offset
|
||||
size_type offset = unsigned_random(size);
|
||||
|
||||
typename range::value_type x = *(r.begin() + offset);
|
||||
// test contains(value_type)
|
||||
assert(r.contains(r.start()) == !r.empty());
|
||||
assert(!r.contains(r.finish()));
|
||||
assert(r.contains(x) == (offset != size));
|
||||
|
||||
range::const_iterator p = r.find(x);
|
||||
assert((p == r.end()) == (x == r.finish()));
|
||||
assert(r.find(r.finish()) == r.end());
|
||||
|
||||
if (offset != size)
|
||||
{
|
||||
assert(x == r[offset]);
|
||||
assert(x == r.at(offset));
|
||||
}
|
||||
|
||||
bool caught_out_of_range = false;
|
||||
try {
|
||||
bool never_initialized = x == r.at(size);
|
||||
(void)never_initialized;
|
||||
}
|
||||
catch(std::out_of_range&)
|
||||
{
|
||||
caught_out_of_range = true;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
}
|
||||
assert(caught_out_of_range);
|
||||
}
|
||||
|
||||
// Those tests must be skipped for other ranges
|
||||
template <class T>
|
||||
void category_test_1(
|
||||
const boost::half_open_range<T>&, std::forward_iterator_tag)
|
||||
{
|
||||
}
|
||||
|
||||
unsigned indices[][2] = { {0,0},{0,1},{0,2},{0,3},
|
||||
{1,1},{1,2},{1,3},
|
||||
{2,2},{2,3},
|
||||
{3,3}};
|
||||
|
||||
template <class Range>
|
||||
void category_test_2(
|
||||
const std::vector<Range>& ranges, unsigned i, unsigned j, std::random_access_iterator_tag)
|
||||
{
|
||||
typedef Range range;
|
||||
const range& ri = ranges[i];
|
||||
const range& rj = ranges[j];
|
||||
|
||||
if (indices[i][0] <= indices[j][0] && indices[i][1] >= indices[j][1])
|
||||
assert(ri.contains(rj));
|
||||
|
||||
if (ri.contains(rj))
|
||||
assert((ri & rj) == rj);
|
||||
assert(boost::intersects(ri, rj) == !(ri & rj).empty());
|
||||
|
||||
range t1(ri);
|
||||
t1 &= rj;
|
||||
assert(t1 == range(indices[i][0] > indices[j][0] ? ri.start() : rj.start(),
|
||||
indices[i][1] < indices[j][1] ? ri.finish() : rj.finish()));
|
||||
assert(t1 == (ri & rj));
|
||||
|
||||
range t2(ri);
|
||||
t2 |= rj;
|
||||
|
||||
if (ri.empty())
|
||||
assert(t2 == rj);
|
||||
else if (rj.empty())
|
||||
assert(t2 == ri);
|
||||
else
|
||||
assert(t2 == range(indices[i][0] < indices[j][0] ? ri.start() : rj.start(),
|
||||
indices[i][1] > indices[j][1] ? ri.finish() : rj.finish()));
|
||||
assert(t2 == (ri | rj));
|
||||
if (i == j)
|
||||
assert(ri == rj);
|
||||
|
||||
if (ri.empty() || rj.empty())
|
||||
assert((ri == rj) == (ri.empty() && rj.empty()));
|
||||
else
|
||||
assert((ri == rj) == (ri.start() == rj.start() && ri.finish() == rj.finish()));
|
||||
|
||||
assert((ri == rj) == !(ri != rj));
|
||||
|
||||
bool same = ri == rj;
|
||||
bool one_empty = ri.empty() != rj.empty();
|
||||
|
||||
std::less<range> less;
|
||||
std::less_equal<range> less_equal;
|
||||
std::greater<range> greater;
|
||||
std::greater_equal<range> greater_equal;
|
||||
|
||||
if (same)
|
||||
{
|
||||
assert(greater_equal(ri,rj));
|
||||
assert(less_equal(ri,rj));
|
||||
assert(!greater(ri,rj));
|
||||
assert(!less(ri,rj));
|
||||
}
|
||||
else if (one_empty)
|
||||
{
|
||||
const range& empty = ri.empty() ? ri : rj;
|
||||
const range& non_empty = rj.empty() ? ri : rj;
|
||||
|
||||
assert(less(empty,non_empty));
|
||||
assert(less_equal(empty,non_empty));
|
||||
assert(!greater(empty,non_empty));
|
||||
assert(!greater_equal(empty,non_empty));
|
||||
assert(!less(non_empty,empty));
|
||||
assert(!less_equal(non_empty,empty));
|
||||
assert(greater(non_empty,empty));
|
||||
assert(greater_equal(non_empty,empty));
|
||||
}
|
||||
else {
|
||||
if (indices[i][0] < indices[j][0] ||
|
||||
indices[i][0] == indices[j][0] && indices[i][1] < indices[j][1])
|
||||
{
|
||||
assert(!greater_equal(ri,rj));
|
||||
assert(less(ri,rj));
|
||||
}
|
||||
|
||||
if (indices[i][0] < indices[j][0] ||
|
||||
indices[i][0] == indices[j][0] && indices[i][1] <= indices[j][1])
|
||||
{
|
||||
assert(!greater(ri,rj));
|
||||
assert(less_equal(ri,rj));
|
||||
}
|
||||
|
||||
if (indices[i][0] > indices[j][0] ||
|
||||
indices[i][0] == indices[j][0] && indices[i][1] > indices[j][1])
|
||||
{
|
||||
assert(!less_equal(ri,rj));
|
||||
assert(greater(ri,rj));
|
||||
}
|
||||
|
||||
if (indices[i][0] > indices[j][0] ||
|
||||
indices[i][0] == indices[j][0] && indices[i][1] >= indices[j][1])
|
||||
{
|
||||
assert(!less(ri,rj));
|
||||
assert(greater_equal(ri,rj));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <class Range>
|
||||
void category_test_2(
|
||||
const std::vector<Range>&, unsigned, unsigned, std::forward_iterator_tag)
|
||||
{
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void category_test_2(
|
||||
const std::vector<boost::half_open_range<T> >&, unsigned, unsigned, std::bidirectional_iterator_tag)
|
||||
{
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
void test_back(Range& x, std::bidirectional_iterator_tag)
|
||||
{
|
||||
assert(x.back() == boost::prior(x.finish()));
|
||||
}
|
||||
|
||||
template <class Range>
|
||||
void test_back(Range& x, std::forward_iterator_tag)
|
||||
{
|
||||
}
|
||||
|
||||
template <class T>
|
||||
boost::half_open_range<T> range_identity(const boost::half_open_range<T>& x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void test(T x0, T x1, T x2, T x3)
|
||||
{
|
||||
std::vector<boost::half_open_range<T> > ranges;
|
||||
typedef boost::half_open_range<T> range;
|
||||
|
||||
T bounds[4] = { x0, x1, x2, x3 };
|
||||
|
||||
const std::size_t num_ranges = sizeof(indices)/sizeof(*indices);
|
||||
// test construction
|
||||
for (std::size_t n = 0; n < num_ranges;++n)
|
||||
{
|
||||
T start = bounds[indices[n][0]];
|
||||
T finish = bounds[indices[n][1]];
|
||||
boost::half_open_range<T> r(start, finish);
|
||||
ranges.push_back(r);
|
||||
}
|
||||
|
||||
// test implicit conversion from std::pair<T,T>
|
||||
range converted = std::pair<T,T>(x0,x0);
|
||||
(void)converted;
|
||||
|
||||
// test assignment, equality and inequality
|
||||
range r00 = range(x0, x0);
|
||||
assert(r00 == range(x0,x0));
|
||||
assert(r00 == range(x1,x1)); // empty ranges are all equal
|
||||
if (x3 != x0)
|
||||
assert(r00 != range(x0, x3));
|
||||
r00 = range(x0, x3);
|
||||
assert(r00 == range(x0, x3));
|
||||
if (x3 != x0)
|
||||
assert(r00 != range(x0, x0));
|
||||
|
||||
typedef typename range::iterator iterator;
|
||||
typedef typename iterator::iterator_category category;
|
||||
|
||||
for (unsigned i = 0; i < num_ranges; ++i)
|
||||
{
|
||||
const range& r = ranges[i];
|
||||
|
||||
// test begin(), end(), basic iteration.
|
||||
unsigned count = 0;
|
||||
for (range::const_iterator p = r.begin(), finish = r.end();
|
||||
p != finish;
|
||||
++p, ++count)
|
||||
{
|
||||
assert(count < 2100);
|
||||
}
|
||||
|
||||
// test size(), empty(), front(), back()
|
||||
assert((unsigned)r.size() == count);
|
||||
if (indices[i][0] == indices[i][1])
|
||||
assert(r.empty());
|
||||
if (r.empty())
|
||||
assert(r.size() == 0);
|
||||
if (!r.empty())
|
||||
{
|
||||
assert(r.front() == r.start());
|
||||
test_back(r, category());
|
||||
}
|
||||
|
||||
// test swap
|
||||
range r1(r);
|
||||
range r2(x0,x3);
|
||||
const bool same = r1 == r2;
|
||||
r1.swap(r2);
|
||||
assert(r1 == range(x0,x3));
|
||||
assert(r2 == r);
|
||||
if (!same) {
|
||||
assert(r1 != r);
|
||||
assert(r2 != range(x0,x3));
|
||||
}
|
||||
|
||||
// do individual tests for random-access iterators
|
||||
category_test_1(r, category());
|
||||
}
|
||||
|
||||
for (unsigned j = 0; j < num_ranges; ++j) {
|
||||
for (unsigned k = 0; k < num_ranges; ++k) {
|
||||
category_test_2(ranges, j, k, category());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template <class Integer>
|
||||
void test_integer(Integer* = 0) // default arg works around MSVC bug
|
||||
{
|
||||
Integer a = 0;
|
||||
Integer b = a + unsigned_random(128 - a);
|
||||
Integer c = b + unsigned_random(128 - b);
|
||||
Integer d = c + unsigned_random(128 - c);
|
||||
|
||||
test(a, b, c, d);
|
||||
}
|
||||
|
||||
template <class Container>
|
||||
void test_container(Container* = 0) // default arg works around MSVC bug
|
||||
{
|
||||
Container c(unsigned_random(1673));
|
||||
|
||||
const typename Container::size_type offset1 = unsigned_random(c.size());
|
||||
const typename Container::size_type offset2 = unsigned_random(c.size() - offset1);
|
||||
typename Container::iterator internal1 = c.begin();
|
||||
std::advance(internal1, offset1);
|
||||
typename Container::iterator internal2 = internal1;
|
||||
std::advance(internal2, offset2);
|
||||
|
||||
test(c.begin(), internal1, internal2, c.end());
|
||||
|
||||
typedef typename Container::const_iterator const_iterator;
|
||||
test(const_iterator(c.begin()),
|
||||
const_iterator(internal1),
|
||||
const_iterator(internal2),
|
||||
const_iterator(c.end()));
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// Test the built-in integer types.
|
||||
test_integer<char>();
|
||||
test_integer<unsigned char>();
|
||||
test_integer<signed char>();
|
||||
test_integer<wchar_t>();
|
||||
test_integer<short>();
|
||||
test_integer<unsigned short>();
|
||||
test_integer<int>();
|
||||
test_integer<unsigned int>();
|
||||
test_integer<long>();
|
||||
test_integer<unsigned long>();
|
||||
#if defined(BOOST_HAS_LONG_LONG)
|
||||
test_integer<long long>();
|
||||
test_integer<unsigned long long>();
|
||||
#endif
|
||||
// Some tests on container iterators, to prove we handle a few different categories
|
||||
test_container<std::vector<int> >();
|
||||
test_container<std::list<int> >();
|
||||
#ifndef BOOST_NO_SLIST
|
||||
test_container<BOOST_STD_EXTENSION_NAMESPACE::slist<int> >();
|
||||
#endif
|
||||
// Also prove that we can handle raw pointers.
|
||||
int array[2000];
|
||||
const std::size_t a = 0;
|
||||
const std::size_t b = a + unsigned_random(2000 - a);
|
||||
const std::size_t c = b + unsigned_random(2000 - b);
|
||||
test(array, array+b, array+c, array+2000);
|
||||
return 0;
|
||||
}
|
297
in_place_factories.html
Normal file
297
in_place_factories.html
Normal file
@@ -0,0 +1,297 @@
|
||||
<!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=iso-8859-1">
|
||||
<LINK REL="stylesheet" TYPE="text/css" HREF="../../boost.css">
|
||||
<TITLE>Header </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 <<A
|
||||
HREF="../../boost/utility/in_place_factory.hpp">boost/utility/in_place_factory.hpp</A>> </H2>
|
||||
|
||||
<H2 align="left">Header <<A
|
||||
HREF="../../boost/utility/typed_in_place_factory.hpp">boost/utility/typed_in_place_factory.hpp</A>> </H2>
|
||||
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
</blockquote>
|
||||
<p> </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 shceme, 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 ftom 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<class InPlaceFactory>
|
||||
C ( InPlaceFactory const& aFactoty )
|
||||
:
|
||||
contained_ ( uninitialized_storage() )
|
||||
{
|
||||
aFactory.template apply<X>(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<class A0>
|
||||
class in_place_factory : public in_place_factory_base
|
||||
{
|
||||
public:</PRE>
|
||||
|
||||
<PRE> in_place_factory ( A0 const& a0 ) : m_a0(a0) {}
|
||||
|
||||
template< class T >
|
||||
void apply ( void* address ) const
|
||||
{
|
||||
new (address) T(m_a0);
|
||||
}
|
||||
|
||||
private:</PRE>
|
||||
|
||||
<PRE> A0 const& m_a0 ;
|
||||
} ;
|
||||
|
||||
template<class A0>
|
||||
in_place_factory<A0> in_place ( A0 const& a0 )
|
||||
{
|
||||
return in_place_factory<A0>(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<class T, class A0>
|
||||
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<class T, class A0>
|
||||
typed_in_place_factory<A0> in_place ( A0 const& a0 )
|
||||
{
|
||||
return typed_in_place_factory<T,A0>(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<class Expr>
|
||||
C ( Expr const& expr )
|
||||
:
|
||||
contained_ ( uninitialized_storage() )
|
||||
{
|
||||
construct(expr,&expr)
|
||||
}
|
||||
|
||||
~C() { delete contained_ ; }
|
||||
|
||||
template<class InPlaceFactory>
|
||||
void construct ( InPlaceFactory const& aFactory, boost::in_place_factory_base* )
|
||||
{
|
||||
aFactory.template apply<X>(contained_);
|
||||
}
|
||||
|
||||
template<class TypedInPlaceFactory>
|
||||
void construct ( TypedInPlaceFactory const& aFactory, boost::typed_in_place_factory_base* )
|
||||
{
|
||||
aFactory.apply(contained_);
|
||||
}
|
||||
|
||||
X* uninitialized_storage() { return static_cast<X*>(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<T>(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<X>(456,"world") ) ; // typed_in_place_factory passed
|
||||
}
|
||||
</pre>
|
||||
|
||||
<P>Revised September 17, 2004</P>
|
||||
<p><EFBFBD> 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>
|
@@ -3,10 +3,9 @@
|
||||
//
|
||||
// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd.
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
// 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)
|
||||
//
|
||||
// Note: There are no include guards. This is intentional.
|
||||
//
|
||||
@@ -33,6 +32,6 @@ void assertion_failed(char const * expr, char const * function, char const * fil
|
||||
#define BOOST_ASSERT(expr) ((expr)? ((void)0): ::boost::assertion_failed(#expr, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__))
|
||||
|
||||
#else
|
||||
# include <assert.h>
|
||||
# include <assert.h> // .h to support old libraries w/o <cassert> - effect is the same
|
||||
# define BOOST_ASSERT(expr) assert(expr)
|
||||
#endif
|
||||
|
@@ -10,15 +10,13 @@
|
||||
//
|
||||
// boost/checked_delete.hpp
|
||||
//
|
||||
// Copyright (c) 1999, 2000, 2001, 2002 boost.org
|
||||
// Copyright (c) 2002, 2003 Peter Dimov
|
||||
// Copyright (c) 2003 Daniel Frey
|
||||
// Copyright (c) 2003 Howard Hinnant
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
// 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/checked_delete.html for documentation.
|
||||
//
|
||||
|
@@ -12,10 +12,9 @@
|
||||
//
|
||||
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
// 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)
|
||||
//
|
||||
// http://www.boost.org/libs/utility/current_function.html
|
||||
//
|
||||
|
@@ -21,13 +21,11 @@
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
#include <boost/config.hpp>
|
||||
#endif
|
||||
#include <cstddef>
|
||||
|
||||
#ifndef BOOST_ARITHMETIC_TYPE_TRAITS_HPP
|
||||
#include <boost/type_traits/arithmetic_traits.hpp>
|
||||
#endif
|
||||
#ifndef BOOST_COMPOSITE_TYPE_TRAITS_HPP
|
||||
#include <boost/type_traits/composite_traits.hpp>
|
||||
#endif
|
||||
#include <boost/type_traits/is_arithmetic.hpp>
|
||||
#include <boost/type_traits/is_pointer.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
namespace boost{
|
||||
|
||||
@@ -94,7 +92,7 @@ struct call_traits<T&>
|
||||
typedef T& param_type; // hh removed const
|
||||
};
|
||||
|
||||
#if defined(__BORLANDC__) && (__BORLANDC__ <= 0x560)
|
||||
#if BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT( 0x570 ) )
|
||||
// these are illegal specialisations; cv-qualifies applied to
|
||||
// references have no effect according to [8.3.2p1],
|
||||
// C++ Builder requires them though as it treats cv-qualified
|
||||
@@ -124,7 +122,7 @@ struct call_traits<T&const volatile>
|
||||
typedef T& param_type; // hh removed const
|
||||
};
|
||||
#endif
|
||||
#ifndef __SUNPRO_CC
|
||||
#if !defined(BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS)
|
||||
template <typename T, std::size_t N>
|
||||
struct call_traits<T [N]>
|
||||
{
|
||||
|
@@ -8,6 +8,9 @@
|
||||
// compressed_pair: pair that "compresses" empty members
|
||||
// (see libs/utility/compressed_pair.htm)
|
||||
//
|
||||
// JM changes 25 Jan 2004:
|
||||
// For the case where T1 == T2 and both are empty, then first() and second()
|
||||
// should return different objects.
|
||||
// JM changes 25 Jan 2000:
|
||||
// Removed default arguments from compressed_pair_switch to get
|
||||
// C++ Builder 4 to accept them
|
||||
@@ -18,15 +21,11 @@
|
||||
#define BOOST_DETAIL_COMPRESSED_PAIR_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#ifndef BOOST_OBJECT_TYPE_TRAITS_HPP
|
||||
#include <boost/type_traits/object_traits.hpp>
|
||||
#endif
|
||||
#ifndef BOOST_SAME_TRAITS_HPP
|
||||
#include <boost/type_traits/same_traits.hpp>
|
||||
#endif
|
||||
#ifndef BOOST_CALL_TRAITS_HPP
|
||||
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
#include <boost/type_traits/is_empty.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/call_traits.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost
|
||||
{
|
||||
@@ -133,7 +132,7 @@ namespace details
|
||||
|
||||
template <class T1, class T2>
|
||||
class compressed_pair_imp<T1, T2, 1>
|
||||
: private T1
|
||||
: private ::boost::remove_cv<T1>::type
|
||||
{
|
||||
public:
|
||||
typedef T1 first_type;
|
||||
@@ -175,7 +174,7 @@ namespace details
|
||||
|
||||
template <class T1, class T2>
|
||||
class compressed_pair_imp<T1, T2, 2>
|
||||
: private T2
|
||||
: private ::boost::remove_cv<T2>::type
|
||||
{
|
||||
public:
|
||||
typedef T1 first_type;
|
||||
@@ -218,8 +217,8 @@ namespace details
|
||||
|
||||
template <class T1, class T2>
|
||||
class compressed_pair_imp<T1, T2, 3>
|
||||
: private T1,
|
||||
private T2
|
||||
: private ::boost::remove_cv<T1>::type,
|
||||
private ::boost::remove_cv<T2>::type
|
||||
{
|
||||
public:
|
||||
typedef T1 first_type;
|
||||
@@ -258,7 +257,7 @@ namespace details
|
||||
// but reuses T1 base class for both first() and second().
|
||||
template <class T1, class T2>
|
||||
class compressed_pair_imp<T1, T2, 4>
|
||||
: private T1
|
||||
: private ::boost::remove_cv<T1>::type
|
||||
{
|
||||
public:
|
||||
typedef T1 first_type;
|
||||
@@ -272,20 +271,21 @@ namespace details
|
||||
|
||||
compressed_pair_imp() {}
|
||||
|
||||
compressed_pair_imp(first_param_type x, second_param_type)
|
||||
: first_type(x) {}
|
||||
compressed_pair_imp(first_param_type x, second_param_type y)
|
||||
: first_type(x), m_second(y) {}
|
||||
|
||||
compressed_pair_imp(first_param_type x)
|
||||
: first_type(x) {}
|
||||
: first_type(x), m_second(x) {}
|
||||
|
||||
first_reference first() {return *this;}
|
||||
first_const_reference first() const {return *this;}
|
||||
|
||||
second_reference second() {return *this;}
|
||||
second_const_reference second() const {return *this;}
|
||||
second_reference second() {return m_second;}
|
||||
second_const_reference second() const {return m_second;}
|
||||
|
||||
void swap(::boost::compressed_pair<T1,T2>&) {}
|
||||
private:
|
||||
T2 m_second;
|
||||
};
|
||||
|
||||
// 5 T1 == T2 and are not empty: //JM
|
||||
@@ -430,5 +430,3 @@ swap(compressed_pair<T1, T2>& x, compressed_pair<T1, T2>& y)
|
||||
|
||||
#endif // BOOST_DETAIL_COMPRESSED_PAIR_HPP
|
||||
|
||||
|
||||
|
||||
|
@@ -292,22 +292,24 @@ public:
|
||||
typedef typename call_traits<second_type>::const_reference second_const_reference;
|
||||
|
||||
compressed_pair_4() : T1() {}
|
||||
compressed_pair_4(first_param_type x, second_param_type) : T1(x) {}
|
||||
compressed_pair_4(first_param_type x, second_param_type y) : T1(x), m_second(y) {}
|
||||
// only one single argument constructor since T1 == T2
|
||||
explicit compressed_pair_4(first_param_type x) : T1(x) {}
|
||||
explicit compressed_pair_4(first_param_type x) : T1(x), m_second(x) {}
|
||||
compressed_pair_4(const ::boost::compressed_pair<T1,T2>& x)
|
||||
: T1(x.first()){}
|
||||
: T1(x.first()), m_second(x.second()) {}
|
||||
|
||||
first_reference first() { return *this; }
|
||||
first_const_reference first() const { return *this; }
|
||||
|
||||
second_reference second() { return *this; }
|
||||
second_const_reference second() const { return *this; }
|
||||
second_reference second() { return m_second; }
|
||||
second_const_reference second() const { return m_second; }
|
||||
|
||||
void swap(compressed_pair_4& y)
|
||||
{
|
||||
// no need to swap empty base classes:
|
||||
}
|
||||
private:
|
||||
T2 m_second;
|
||||
};
|
||||
|
||||
// T1 == T2, not empty
|
||||
|
@@ -1,8 +1,7 @@
|
||||
// (C) Copyright Jens Maurer 2001. Permission to copy, use,
|
||||
// modify, sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
// (C) Copyright Jens Maurer 2001.
|
||||
// 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)
|
||||
//
|
||||
// Revision History:
|
||||
|
||||
|
@@ -1,10 +1,8 @@
|
||||
// Boost next_prior.hpp header file ---------------------------------------//
|
||||
|
||||
// (C) Copyright Boost.org 1999-2003. Permission to copy, use, modify, sell
|
||||
// and distribute this software is granted provided this copyright
|
||||
// notice appears in all copies. This software is provided "as is" without
|
||||
// express or implied warranty, and with no claim as to its suitability for
|
||||
// any purpose.
|
||||
// (C) Copyright Dave Abrahams and Daniel Walker 1999-2003. 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.
|
||||
|
||||
|
@@ -1,10 +1,8 @@
|
||||
// Boost noncopyable.hpp header file --------------------------------------//
|
||||
|
||||
// (C) Copyright Boost.org 1999-2003. Permission to copy, use, modify, sell
|
||||
// and distribute this software is granted provided this copyright
|
||||
// notice appears in all copies. This software is provided "as is" without
|
||||
// express or implied warranty, and with no claim as to its suitability for
|
||||
// any purpose.
|
||||
// (C) Copyright Beman Dawes 1999-2003. 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.
|
||||
|
||||
@@ -18,15 +16,20 @@ namespace boost {
|
||||
|
||||
// Contributed by Dave Abrahams
|
||||
|
||||
class noncopyable
|
||||
namespace noncopyable_ // protection from unintended ADL
|
||||
{
|
||||
protected:
|
||||
noncopyable() {}
|
||||
~noncopyable() {}
|
||||
private: // emphasize the following members are private
|
||||
noncopyable( const noncopyable& );
|
||||
const noncopyable& operator=( const noncopyable& );
|
||||
};
|
||||
class noncopyable
|
||||
{
|
||||
protected:
|
||||
noncopyable() {}
|
||||
~noncopyable() {}
|
||||
private: // emphasize the following members are private
|
||||
noncopyable( const noncopyable& );
|
||||
const noncopyable& operator=( const noncopyable& );
|
||||
};
|
||||
}
|
||||
|
||||
typedef noncopyable_::noncopyable noncopyable;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
@@ -1,10 +1,9 @@
|
||||
// Boost operators.hpp header file ----------------------------------------//
|
||||
|
||||
// (C) Copyright David Abrahams, Jeremy Siek, and Daryle Walker 1999-2001.
|
||||
// Permission to copy, use, modify, sell and distribute this software is
|
||||
// granted provided this copyright notice appears in all copies. This
|
||||
// software is provided "as is" without express or implied warranty, and
|
||||
// with no claim as to its suitability for any purpose.
|
||||
// (C) Copyright David Abrahams, Jeremy Siek, Daryle Walker 1999-2001.
|
||||
// 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/operators.htm for documentation.
|
||||
|
||||
@@ -675,7 +674,7 @@ struct random_access_iteratable
|
||||
// Here's where we put it all together, defining the xxxx forms of the templates
|
||||
// in namespace boost. We also define specializations of is_chained_base<> for
|
||||
// the xxxx, xxxx1, and xxxx2 templates, importing them into boost:: as
|
||||
// neccessary.
|
||||
// necessary.
|
||||
//
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
@@ -700,7 +699,7 @@ template<class T> struct is_chained_base {
|
||||
|
||||
} // namespace boost
|
||||
|
||||
// Import a 4-type-argument operator template into boost (if neccessary) and
|
||||
// Import a 4-type-argument operator template into boost (if necessary) and
|
||||
// provide a specialization of 'is_chained_base<>' for it.
|
||||
# define BOOST_OPERATOR_TEMPLATE4(template_name4) \
|
||||
BOOST_IMPORT_TEMPLATE4(template_name4) \
|
||||
@@ -709,7 +708,7 @@ template<class T> struct is_chained_base {
|
||||
typedef ::boost::detail::true_t value; \
|
||||
};
|
||||
|
||||
// Import a 3-type-argument operator template into boost (if neccessary) and
|
||||
// Import a 3-type-argument operator template into boost (if necessary) and
|
||||
// provide a specialization of 'is_chained_base<>' for it.
|
||||
# define BOOST_OPERATOR_TEMPLATE3(template_name3) \
|
||||
BOOST_IMPORT_TEMPLATE3(template_name3) \
|
||||
@@ -718,7 +717,7 @@ template<class T> struct is_chained_base {
|
||||
typedef ::boost::detail::true_t value; \
|
||||
};
|
||||
|
||||
// Import a 2-type-argument operator template into boost (if neccessary) and
|
||||
// Import a 2-type-argument operator template into boost (if necessary) and
|
||||
// provide a specialization of 'is_chained_base<>' for it.
|
||||
# define BOOST_OPERATOR_TEMPLATE2(template_name2) \
|
||||
BOOST_IMPORT_TEMPLATE2(template_name2) \
|
||||
@@ -727,7 +726,7 @@ template<class T> struct is_chained_base {
|
||||
typedef ::boost::detail::true_t value; \
|
||||
};
|
||||
|
||||
// Import a 1-type-argument operator template into boost (if neccessary) and
|
||||
// Import a 1-type-argument operator template into boost (if necessary) and
|
||||
// provide a specialization of 'is_chained_base<>' for it.
|
||||
# define BOOST_OPERATOR_TEMPLATE1(template_name1) \
|
||||
BOOST_IMPORT_TEMPLATE1(template_name1) \
|
||||
|
@@ -18,10 +18,9 @@
|
||||
// Copyright (C) 2001, 2002 Peter Dimov
|
||||
// Copyright (C) 2002 David Abrahams
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
// 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/bind/ref.html for documentation.
|
||||
//
|
||||
@@ -40,7 +39,7 @@ public:
|
||||
|
||||
#else
|
||||
|
||||
explicit reference_wrapper(T& t): t_(addressof(t)) {}
|
||||
explicit reference_wrapper(T& t): t_(boost::addressof(t)) {}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -74,18 +73,13 @@ template<class T> inline reference_wrapper<T const> BOOST_REF_CONST cref(T const
|
||||
# undef BOOST_REF_CONST
|
||||
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
template<typename T>
|
||||
class is_reference_wrapper
|
||||
: public mpl::false_
|
||||
{
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class is_reference_wrapper<reference_wrapper<T> >
|
||||
: public mpl::true_
|
||||
{
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class unwrap_reference
|
||||
{
|
||||
@@ -93,12 +87,30 @@ class unwrap_reference
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class unwrap_reference<reference_wrapper<T> >
|
||||
{
|
||||
public:
|
||||
typedef T type;
|
||||
};
|
||||
# define AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF(X) \
|
||||
template<typename T> \
|
||||
class is_reference_wrapper< X > \
|
||||
: public mpl::true_ \
|
||||
{ \
|
||||
}; \
|
||||
\
|
||||
template<typename T> \
|
||||
class unwrap_reference< X > \
|
||||
{ \
|
||||
public: \
|
||||
typedef T type; \
|
||||
}; \
|
||||
/**/
|
||||
|
||||
AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF(reference_wrapper<T>)
|
||||
#if !defined(BOOST_NO_CV_SPECIALIZATIONS)
|
||||
AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF(reference_wrapper<T> const)
|
||||
AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF(reference_wrapper<T> volatile)
|
||||
AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF(reference_wrapper<T> const volatile)
|
||||
#endif
|
||||
|
||||
# undef AUX_REFERENCE_WRAPPER_METAFUNCTIONS_DEF
|
||||
|
||||
# else // no partial specialization
|
||||
|
||||
} // namespace boost
|
||||
|
@@ -1,6 +1,6 @@
|
||||
// Boost utility.hpp header file -------------------------------------------//
|
||||
|
||||
// Copyright 1999-2003 Boost.org. Use, modification, and distribution are
|
||||
// Copyright 1999-2003 Aleksey Gurtovoy. 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>.)
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include <boost/utility/addressof.hpp>
|
||||
#include <boost/utility/base_from_member.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/checked_delete.hpp>
|
||||
#include <boost/next_prior.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
|
@@ -1,15 +1,10 @@
|
||||
// Copyright (C) 2002 Brad King (brad.king@kitware.com)
|
||||
// Doug Gregor (gregod@cs.rpi.edu)
|
||||
// Douglas Gregor (gregod@cs.rpi.edu)
|
||||
// Peter Dimov
|
||||
//
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
// 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
|
||||
|
||||
@@ -18,9 +13,6 @@
|
||||
|
||||
# include <boost/config.hpp>
|
||||
# include <boost/detail/workaround.hpp>
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
|
||||
# include <boost/type_traits/add_pointer.hpp>
|
||||
# endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
@@ -28,7 +20,14 @@ namespace boost {
|
||||
|
||||
// VC7 strips const from nested classes unless we add indirection here
|
||||
# if BOOST_WORKAROUND(BOOST_MSVC, == 1300)
|
||||
template <typename T> typename add_pointer<T>::type
|
||||
|
||||
template<class T> struct _addp
|
||||
{
|
||||
typedef T * type;
|
||||
};
|
||||
|
||||
template <typename T> typename _addp<T>::type
|
||||
|
||||
# else
|
||||
template <typename T> T*
|
||||
# endif
|
||||
@@ -38,6 +37,22 @@ addressof(T& v)
|
||||
&const_cast<char&>(reinterpret_cast<const volatile char &>(v)));
|
||||
}
|
||||
|
||||
// Borland doesn't like casting an array reference to a char reference
|
||||
// but these overloads work around the problem.
|
||||
# if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||
template<typename T,std::size_t N>
|
||||
T (*addressof(T (&t)[N]))[N]
|
||||
{
|
||||
return reinterpret_cast<T(*)[N]>(&t);
|
||||
}
|
||||
|
||||
template<typename T,std::size_t N>
|
||||
const T (*addressof(const T (&t)[N]))[N]
|
||||
{
|
||||
return reinterpret_cast<const T(*)[N]>(&t);
|
||||
}
|
||||
# endif
|
||||
|
||||
}
|
||||
|
||||
#endif // BOOST_UTILITY_ADDRESSOF_HPP
|
||||
|
@@ -1,15 +1,53 @@
|
||||
// boost utility/base_from_member.hpp header file --------------------------//
|
||||
|
||||
// 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>.)
|
||||
// Copyright 2001, 2003, 2004 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.
|
||||
|
||||
#ifndef BOOST_UTILITY_BASE_FROM_MEMBER_HPP
|
||||
#define BOOST_UTILITY_BASE_FROM_MEMBER_HPP
|
||||
|
||||
#include <boost/utility_fwd.hpp> // required for parameter defaults
|
||||
#include <boost/preprocessor/arithmetic/inc.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
|
||||
|
||||
|
||||
// Base-from-member arity configuration macro ------------------------------//
|
||||
|
||||
// The following macro determines how many arguments will be in the largest
|
||||
// constructor template of base_from_member. Constructor templates will be
|
||||
// generated from one argument to this maximum. Code from other files can read
|
||||
// this number if they need to always match the exact maximum base_from_member
|
||||
// uses. The maximum constructor length can be changed by overriding the
|
||||
// #defined constant. Make sure to apply the override, if any, for all source
|
||||
// files during project compiling for consistency.
|
||||
|
||||
// Contributed by Jonathan Turkanis
|
||||
|
||||
#ifndef BOOST_BASE_FROM_MEMBER_MAX_ARITY
|
||||
#define BOOST_BASE_FROM_MEMBER_MAX_ARITY 10
|
||||
#endif
|
||||
|
||||
|
||||
// An iteration of a constructor template for base_from_member -------------//
|
||||
|
||||
// A macro that should expand to:
|
||||
// template < typename T1, ..., typename Tn >
|
||||
// base_from_member( T1 x1, ..., Tn xn )
|
||||
// : member( x1, ..., xn )
|
||||
// {}
|
||||
// This macro should only persist within this file.
|
||||
|
||||
#define BOOST_PRIVATE_CTR_DEF( z, n, data ) \
|
||||
template < BOOST_PP_ENUM_PARAMS(n, typename T) > \
|
||||
explicit base_from_member( BOOST_PP_ENUM_BINARY_PARAMS(n, T, x) ) \
|
||||
: member( BOOST_PP_ENUM_PARAMS(n, x) ) \
|
||||
{} \
|
||||
/**/
|
||||
|
||||
|
||||
namespace boost
|
||||
@@ -24,7 +62,7 @@ namespace boost
|
||||
|
||||
// Contributed by Daryle Walker
|
||||
|
||||
template < typename MemberType, int UniqueID >
|
||||
template < typename MemberType, int UniqueID = 0 >
|
||||
class base_from_member
|
||||
{
|
||||
protected:
|
||||
@@ -34,66 +72,16 @@ protected:
|
||||
: member()
|
||||
{}
|
||||
|
||||
template< typename T1 >
|
||||
explicit base_from_member( T1 x1 )
|
||||
: member( x1 )
|
||||
{}
|
||||
|
||||
template< typename T1, typename T2 >
|
||||
base_from_member( T1 x1, T2 x2 )
|
||||
: member( x1, x2 )
|
||||
{}
|
||||
|
||||
template< typename T1, typename T2, typename T3 >
|
||||
base_from_member( T1 x1, T2 x2, T3 x3 )
|
||||
: member( x1, x2, x3 )
|
||||
{}
|
||||
|
||||
template< typename T1, typename T2, typename T3, typename T4 >
|
||||
base_from_member( T1 x1, T2 x2, T3 x3, T4 x4 )
|
||||
: member( x1, x2, x3, x4 )
|
||||
{}
|
||||
|
||||
template< typename T1, typename T2, typename T3, typename T4, typename T5 >
|
||||
base_from_member( T1 x1, T2 x2, T3 x3, T4 x4, T5 x5 )
|
||||
: member( x1, x2, x3, x4, x5 )
|
||||
{}
|
||||
|
||||
template< typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||
typename T6 >
|
||||
base_from_member( T1 x1, T2 x2, T3 x3, T4 x4, T5 x5, T6 x6 )
|
||||
: member( x1, x2, x3, x4, x5, x6 )
|
||||
{}
|
||||
|
||||
template< typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||
typename T6, typename T7 >
|
||||
base_from_member( T1 x1, T2 x2, T3 x3, T4 x4, T5 x5, T6 x6, T7 x7 )
|
||||
: member( x1, x2, x3, x4, x5, x6, x7 )
|
||||
{}
|
||||
|
||||
template< typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||
typename T6, typename T7, typename T8 >
|
||||
base_from_member( T1 x1, T2 x2, T3 x3, T4 x4, T5 x5, T6 x6, T7 x7, T8 x8 )
|
||||
: member( x1, x2, x3, x4, x5, x6, x7, x8 )
|
||||
{}
|
||||
|
||||
template< typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||
typename T6, typename T7, typename T8, typename T9 >
|
||||
base_from_member( T1 x1, T2 x2, T3 x3, T4 x4, T5 x5, T6 x6, T7 x7, T8 x8,
|
||||
T9 x9 )
|
||||
: member( x1, x2, x3, x4, x5, x6, x7, x8, x9 )
|
||||
{}
|
||||
|
||||
template< typename T1, typename T2, typename T3, typename T4, typename T5,
|
||||
typename T6, typename T7, typename T8, typename T9, typename T10 >
|
||||
base_from_member( T1 x1, T2 x2, T3 x3, T4 x4, T5 x5, T6 x6, T7 x7, T8 x8,
|
||||
T9 x9, T10 x10 )
|
||||
: member( x1, x2, x3, x4, x5, x6, x7, x8, x9, x10 )
|
||||
{}
|
||||
BOOST_PP_REPEAT_FROM_TO( 1, BOOST_PP_INC(BOOST_BASE_FROM_MEMBER_MAX_ARITY),
|
||||
BOOST_PRIVATE_CTR_DEF, _ )
|
||||
|
||||
}; // boost::base_from_member
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
||||
// Undo any private macros
|
||||
#undef BOOST_PRIVATE_CTR_DEF
|
||||
|
||||
|
||||
#endif // BOOST_UTILITY_BASE_FROM_MEMBER_HPP
|
||||
|
33
include/boost/utility/detail/in_place_factory_prefix.hpp
Normal file
33
include/boost/utility/detail/in_place_factory_prefix.hpp
Normal file
@@ -0,0 +1,33 @@
|
||||
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
|
||||
//
|
||||
// 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)
|
||||
//
|
||||
// See http://www.boost.org/lib/optional for documentation.
|
||||
//
|
||||
// You are welcome to contact the author at:
|
||||
// fernando_cacciola@hotmail.com
|
||||
//
|
||||
#ifndef BOOST_UTILITY_DETAIL_INPLACE_FACTORY_PREFIX_25AGO2003_HPP
|
||||
#define BOOST_UTILITY_DETAIL_INPLACE_FACTORY_PREFIX_25AGO2003_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/preprocessor/repetition/enum.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/preprocessor/arithmetic/inc.hpp>
|
||||
#include <boost/preprocessor/punctuation/paren.hpp>
|
||||
#include <boost/preprocessor/facilities/empty.hpp>
|
||||
|
||||
#define BOOST_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_INIT(z,n,_) BOOST_PP_CAT(m_a,n) BOOST_PP_LPAREN() BOOST_PP_CAT(a,n) BOOST_PP_RPAREN()
|
||||
#define BOOST_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_DECL(z,n,_) BOOST_PP_CAT(A,n) const& BOOST_PP_CAT(m_a,n);
|
||||
#define BOOST_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_ARG(z,n,_) BOOST_PP_CAT(m_a,n)
|
||||
|
||||
#define BOOST_MAX_INPLACE_FACTORY_ARITY 10
|
||||
|
||||
#undef BOOST_UTILITY_DETAIL_INPLACE_FACTORY_SUFFIX_25AGO2003_HPP
|
||||
|
||||
#endif
|
||||
|
23
include/boost/utility/detail/in_place_factory_suffix.hpp
Normal file
23
include/boost/utility/detail/in_place_factory_suffix.hpp
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
|
||||
//
|
||||
// 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)
|
||||
//
|
||||
// See http://www.boost.org/lib/optional for documentation.
|
||||
//
|
||||
// You are welcome to contact the author at:
|
||||
// fernando_cacciola@hotmail.com
|
||||
//
|
||||
#ifndef BOOST_UTILITY_DETAIL_INPLACE_FACTORY_SUFFIX_25AGO2003_HPP
|
||||
#define BOOST_UTILITY_DETAIL_INPLACE_FACTORY_SUFFIX_25AGO2003_HPP
|
||||
|
||||
#undef BOOST_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_INIT
|
||||
#undef BOOST_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_DECL
|
||||
#undef BOOST_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_ARG
|
||||
#undef BOOST_MAX_INPLACE_FACTORY_ARITY
|
||||
|
||||
#undef BOOST_UTILITY_DETAIL_INPLACE_FACTORY_PREFIX_25AGO2003_HPP
|
||||
|
||||
#endif
|
||||
|
86
include/boost/utility/detail/result_of_iterate.hpp
Normal file
86
include/boost/utility/detail/result_of_iterate.hpp
Normal file
@@ -0,0 +1,86 @@
|
||||
// Boost result_of library
|
||||
|
||||
// Copyright Douglas Gregor 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)
|
||||
|
||||
// For more information, see http://www.boost.org/libs/utility
|
||||
#if !defined(BOOST_PP_IS_ITERATING)
|
||||
# error Boost result_of - do not include this file!
|
||||
#endif
|
||||
|
||||
// CWPro8 requires an argument in a function type specialization
|
||||
#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3002)) && BOOST_PP_ITERATION() == 0
|
||||
# define BOOST_RESULT_OF_ARGS void
|
||||
#else
|
||||
# define BOOST_RESULT_OF_ARGS BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),T)
|
||||
#endif
|
||||
|
||||
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||
template<typename F BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
struct result_of<F(BOOST_RESULT_OF_ARGS)>
|
||||
: detail::result_of<F, F(BOOST_RESULT_OF_ARGS)> {};
|
||||
#endif
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
struct result_of<R (*)(BOOST_RESULT_OF_ARGS), FArgs>
|
||||
{
|
||||
typedef R type;
|
||||
};
|
||||
|
||||
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
struct result_of<R (&)(BOOST_RESULT_OF_ARGS), FArgs>
|
||||
{
|
||||
typedef R type;
|
||||
};
|
||||
|
||||
#undef BOOST_RESULT_OF_ARGS
|
||||
|
||||
#if BOOST_PP_ITERATION() > 1 && !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
|
||||
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
struct result_of<R (T0::*)
|
||||
(BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T)),
|
||||
FArgs>
|
||||
{
|
||||
typedef R type;
|
||||
};
|
||||
|
||||
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
struct result_of<R (T0::*)
|
||||
(BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T))
|
||||
const,
|
||||
FArgs>
|
||||
{
|
||||
typedef R type;
|
||||
};
|
||||
|
||||
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
struct result_of<R (T0::*)
|
||||
(BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T))
|
||||
volatile,
|
||||
FArgs>
|
||||
{
|
||||
typedef R type;
|
||||
};
|
||||
|
||||
template<typename R, typename FArgs BOOST_PP_COMMA_IF(BOOST_PP_ITERATION())
|
||||
BOOST_PP_ENUM_PARAMS(BOOST_PP_ITERATION(),typename T)>
|
||||
struct result_of<R (T0::*)
|
||||
(BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_ITERATION(),T))
|
||||
const volatile,
|
||||
FArgs>
|
||||
{
|
||||
typedef R type;
|
||||
};
|
||||
#endif
|
||||
|
||||
}
|
58
include/boost/utility/in_place_factory.hpp
Normal file
58
include/boost/utility/in_place_factory.hpp
Normal file
@@ -0,0 +1,58 @@
|
||||
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
|
||||
//
|
||||
// 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)
|
||||
//
|
||||
// See http://www.boost.org/lib/optional for documentation.
|
||||
//
|
||||
// You are welcome to contact the author at:
|
||||
// fernando_cacciola@hotmail.com
|
||||
//
|
||||
#ifndef BOOST_UTILITY_INPLACE_FACTORY_25AGO2003_HPP
|
||||
#define BOOST_UTILITY_INPLACE_FACTORY_25AGO2003_HPP
|
||||
|
||||
#include <boost/utility/detail/in_place_factory_prefix.hpp>
|
||||
|
||||
#include <boost/type.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
class in_place_factory_base {} ;
|
||||
|
||||
#define BOOST_DEFINE_INPLACE_FACTORY_CLASS(z,n,_) \
|
||||
template< BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(n),class A) > \
|
||||
class BOOST_PP_CAT(in_place_factory, BOOST_PP_INC(n) ) : public in_place_factory_base \
|
||||
{ \
|
||||
public: \
|
||||
\
|
||||
BOOST_PP_CAT(in_place_factory, BOOST_PP_INC(n) ) ( BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_INC(n),A,const& a) ) \
|
||||
: \
|
||||
BOOST_PP_ENUM( BOOST_PP_INC(n), BOOST_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_INIT, _ ) \
|
||||
{} \
|
||||
\
|
||||
template<class T> \
|
||||
void apply ( void* address BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(T) ) const \
|
||||
{ \
|
||||
new ( address ) T ( BOOST_PP_ENUM_PARAMS( BOOST_PP_INC(n), m_a ) ) ; \
|
||||
} \
|
||||
\
|
||||
BOOST_PP_REPEAT( BOOST_PP_INC(n), BOOST_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_DECL, _) \
|
||||
} ; \
|
||||
\
|
||||
template< BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(n),class A) > \
|
||||
BOOST_PP_CAT(in_place_factory, BOOST_PP_INC(n) ) < BOOST_PP_ENUM_PARAMS( BOOST_PP_INC(n), A ) > \
|
||||
in_place ( BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_INC(n),A, const& a) ) \
|
||||
{ \
|
||||
return BOOST_PP_CAT(in_place_factory, BOOST_PP_INC(n) ) < BOOST_PP_ENUM_PARAMS( BOOST_PP_INC(n), A ) > \
|
||||
( BOOST_PP_ENUM_PARAMS( BOOST_PP_INC(n), a ) ) ; \
|
||||
} ; \
|
||||
|
||||
BOOST_PP_REPEAT( BOOST_MAX_INPLACE_FACTORY_ARITY, BOOST_DEFINE_INPLACE_FACTORY_CLASS, BOOST_PP_EMPTY() )
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/utility/detail/in_place_factory_suffix.hpp>
|
||||
|
||||
#endif
|
||||
|
66
include/boost/utility/result_of.hpp
Normal file
66
include/boost/utility/result_of.hpp
Normal file
@@ -0,0 +1,66 @@
|
||||
// Boost result_of library
|
||||
|
||||
// Copyright Douglas Gregor 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)
|
||||
|
||||
// For more information, see http://www.boost.org/libs/utility
|
||||
#ifndef BOOST_RESULT_OF_HPP
|
||||
#define BOOST_RESULT_OF_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/type_traits/ice.hpp>
|
||||
#include <boost/type.hpp>
|
||||
#include <boost/preprocessor.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/mpl/has_xxx.hpp>
|
||||
|
||||
#ifndef BOOST_RESULT_OF_NUM_ARGS
|
||||
# define BOOST_RESULT_OF_NUM_ARGS 10
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
template<typename F> struct result_of;
|
||||
|
||||
#if !defined(BOOST_NO_SFINAE) && !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
namespace detail {
|
||||
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(result_type)
|
||||
|
||||
template<typename F, typename FArgs, bool HasResultType> struct get_result_of;
|
||||
|
||||
template<typename F, typename FArgs>
|
||||
struct get_result_of<F, FArgs, true>
|
||||
{
|
||||
typedef typename F::result_type type;
|
||||
};
|
||||
|
||||
template<typename F, typename FArgs>
|
||||
struct get_result_of<F, FArgs, false>
|
||||
{
|
||||
typedef typename F::template result<FArgs>::type type;
|
||||
};
|
||||
|
||||
template<typename F>
|
||||
struct get_result_of<F, F(void), false>
|
||||
{
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
template<typename F, typename FArgs>
|
||||
struct result_of : get_result_of<F, FArgs, (has_result_type<F>::value)> {};
|
||||
|
||||
} // end namespace detail
|
||||
|
||||
#define BOOST_PP_ITERATION_PARAMS_1 (3,(0,BOOST_RESULT_OF_NUM_ARGS,<boost/utility/detail/result_of_iterate.hpp>))
|
||||
#include BOOST_PP_ITERATE()
|
||||
|
||||
#else
|
||||
# define BOOST_NO_RESULT_OF 1
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#endif // BOOST_RESULT_OF_HPP
|
57
include/boost/utility/typed_in_place_factory.hpp
Normal file
57
include/boost/utility/typed_in_place_factory.hpp
Normal file
@@ -0,0 +1,57 @@
|
||||
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
|
||||
//
|
||||
// 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)
|
||||
//
|
||||
// See http://www.boost.org/lib/optional for documentation.
|
||||
//
|
||||
// You are welcome to contact the author at:
|
||||
// fernando_cacciola@hotmail.com
|
||||
//
|
||||
#ifndef BOOST_UTILITY_TYPED_INPLACE_FACTORY_25AGO2003_HPP
|
||||
#define BOOST_UTILITY_TYPED_INPLACE_FACTORY_25AGO2003_HPP
|
||||
|
||||
#include <boost/utility/detail/in_place_factory_prefix.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
class typed_in_place_factory_base {} ;
|
||||
|
||||
#define BOOST_DEFINE_TYPED_INPLACE_FACTORY_CLASS(z,n,_) \
|
||||
template< class T, BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(n),class A) > \
|
||||
class BOOST_PP_CAT(typed_in_place_factory, BOOST_PP_INC(n) ) : public typed_in_place_factory_base \
|
||||
{ \
|
||||
public: \
|
||||
\
|
||||
typedef T value_type ; \
|
||||
\
|
||||
BOOST_PP_CAT(typed_in_place_factory, BOOST_PP_INC(n) ) ( BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_INC(n),A,const& a) ) \
|
||||
: \
|
||||
BOOST_PP_ENUM( BOOST_PP_INC(n), BOOST_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_INIT, _ ) \
|
||||
{} \
|
||||
\
|
||||
void apply ( void* address ) const \
|
||||
{ \
|
||||
new ( address ) T ( BOOST_PP_ENUM_PARAMS( BOOST_PP_INC(n), m_a ) ) ; \
|
||||
} \
|
||||
\
|
||||
BOOST_PP_REPEAT( BOOST_PP_INC(n), BOOST_DEFINE_INPLACE_FACTORY_CLASS_MEMBER_DECL, _) \
|
||||
} ; \
|
||||
\
|
||||
template< class T, BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(n),class A) > \
|
||||
BOOST_PP_CAT(typed_in_place_factory, BOOST_PP_INC(n) ) < T , BOOST_PP_ENUM_PARAMS( BOOST_PP_INC(n), A ) > \
|
||||
in_place ( BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_INC(n),A, const& a) ) \
|
||||
{ \
|
||||
return BOOST_PP_CAT(typed_in_place_factory, BOOST_PP_INC(n) ) < T, BOOST_PP_ENUM_PARAMS( BOOST_PP_INC(n), A ) > \
|
||||
( BOOST_PP_ENUM_PARAMS( BOOST_PP_INC(n), a ) ) ; \
|
||||
} ; \
|
||||
|
||||
BOOST_PP_REPEAT( BOOST_MAX_INPLACE_FACTORY_ARITY, BOOST_DEFINE_TYPED_INPLACE_FACTORY_CLASS, BOOST_PP_EMPTY() )
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/utility/detail/in_place_factory_suffix.hpp>
|
||||
|
||||
#endif
|
||||
|
@@ -1,13 +1,8 @@
|
||||
// (C) 2002, Fernando Luis Cacciola Carballal.
|
||||
//
|
||||
// This material is provided "as is", with absolutely no warranty expressed
|
||||
// or implied. Any use is at your own risk.
|
||||
//
|
||||
// Permission to use or copy this software for any purpose is hereby granted
|
||||
// without fee, provided the above notices are retained on all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted,
|
||||
// provided the above notices are retained, and a notice that the code was
|
||||
// modified is included with the above copyright notice.
|
||||
// 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)
|
||||
//
|
||||
// 21 Ago 2002 (Created) Fernando Cacciola
|
||||
//
|
||||
|
@@ -1,33 +0,0 @@
|
||||
// Boost utility_fwd.hpp header file ---------------------------------------//
|
||||
|
||||
// Copyright 2001, 2003 Boost.org. 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.
|
||||
|
||||
#ifndef BOOST_UTILITY_FWD_HPP
|
||||
#define BOOST_UTILITY_FWD_HPP
|
||||
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
|
||||
// From <boost/utility/base_from_member.hpp> -------------------------------//
|
||||
|
||||
template < typename MemberType, int UniqueID = 0 >
|
||||
class base_from_member;
|
||||
|
||||
|
||||
// From <boost/noncopyable.hpp> --------------------------------------------//
|
||||
|
||||
class noncopyable;
|
||||
|
||||
// Also has a few function templates
|
||||
|
||||
|
||||
} // namespace boost
|
||||
|
||||
|
||||
#endif // BOOST_UTILITY_FWD_HPP
|
@@ -7,7 +7,7 @@
|
||||
<title>Boost Utility Library</title>
|
||||
</head>
|
||||
<body bgcolor="#FFFFFF">
|
||||
<h1><IMG SRC="../../c++boost.gif" WIDTH="276" HEIGHT="86" align="center">Boost
|
||||
<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>
|
||||
|
@@ -1,444 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta name="generator" content="HTML Tidy, see www.w3.org">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
||||
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
|
||||
<meta name="ProgId" content="FrontPage.Editor.Document">
|
||||
|
||||
<title>Indirect Iterator Adaptor Documentation</title>
|
||||
</head>
|
||||
|
||||
<body bgcolor="#FFFFFF" text="#000000">
|
||||
|
||||
<img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align=
|
||||
"center" width="277" height="86">
|
||||
|
||||
<h1>Indirect Iterator Adaptor</h1>
|
||||
Defined in header <a href=
|
||||
"../../boost/iterator_adaptors.hpp">boost/iterator_adaptors.hpp</a>
|
||||
|
||||
<p>The indirect iterator adaptor augments an iterator by applying an
|
||||
<b>extra</b> dereference inside of <tt>operator*()</tt>. For example, this
|
||||
iterator makes it possible to view a container of pointers or
|
||||
smart-pointers (e.g. <tt>std::list<boost::shared_ptr<foo>
|
||||
></tt>) as if it were a container of the pointed-to type. The following
|
||||
<b>pseudo-code</b> shows the basic idea of the indirect iterator:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
// inside a hypothetical indirect_iterator class...
|
||||
typedef std::iterator_traits<BaseIterator>::value_type Pointer;
|
||||
typedef std::iterator_traits<Pointer>::reference reference;
|
||||
|
||||
reference indirect_iterator::operator*() const {
|
||||
return **this->base_iterator;
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<h2>Synopsis</h2>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
namespace boost {
|
||||
template <class BaseIterator,
|
||||
class Value, class Reference, class Category, class Pointer>
|
||||
struct indirect_iterator_generator;
|
||||
|
||||
template <class BaseIterator,
|
||||
class Value, class Reference, class ConstReference,
|
||||
class Category, class Pointer, class ConstPointer>
|
||||
struct indirect_iterator_pair_generator;
|
||||
|
||||
template <class BaseIterator>
|
||||
typename indirect_iterator_generator<BaseIterator>::type
|
||||
make_indirect_iterator(BaseIterator base)
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
<hr>
|
||||
|
||||
<h2><a name="indirect_iterator_generator">The Indirect Iterator Type
|
||||
Generator</a></h2>
|
||||
The <tt>indirect_iterator_generator</tt> template is a <a href=
|
||||
"../../more/generic_programming.html#type_generator">generator</a> of
|
||||
indirect iterator types. The main template parameter for this class is the
|
||||
<tt>BaseIterator</tt> type that is being wrapped. In most cases the type of
|
||||
the elements being pointed to can be deduced using
|
||||
<tt>std::iterator_traits</tt>, but in some situations the user may want to
|
||||
override this type, so there are also template parameters that allow a user
|
||||
to control the <tt>value_type</tt>, <tt>pointer</tt>, and
|
||||
<tt>reference</tt> types of the resulting iterators.
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
template <class BaseIterator,
|
||||
class Value, class Reference, class Pointer>
|
||||
class indirect_iterator_generator
|
||||
{
|
||||
public:
|
||||
typedef <tt><a href=
|
||||
"./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a><...></tt> type; // the resulting indirect iterator type
|
||||
};
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<h3>Example</h3>
|
||||
This example uses the <tt>indirect_iterator_generator</tt> to create
|
||||
indirect iterators which dereference the pointers stored in the
|
||||
<tt>pointers_to_chars</tt> array to access the <tt>char</tt>s in the
|
||||
<tt>characters</tt> array.
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
#include <boost/config.hpp>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <boost/iterator_adaptors.hpp>
|
||||
|
||||
int main(int, char*[])
|
||||
{
|
||||
char characters[] = "abcdefg";
|
||||
const int N = sizeof(characters)/sizeof(char) - 1; // -1 since characters has a null char
|
||||
char* pointers_to_chars[N]; // at the end.
|
||||
for (int i = 0; i < N; ++i)
|
||||
pointers_to_chars[i] = &characters[i];
|
||||
|
||||
boost::indirect_iterator_generator<char**, char>::type
|
||||
indirect_first(pointers_to_chars), indirect_last(pointers_to_chars + N);
|
||||
|
||||
std::copy(indirect_first, indirect_last, std::ostream_iterator<char>(std::cout, ","));
|
||||
std::cout << std::endl;
|
||||
|
||||
// to be continued...
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<h3>Template Parameters</h3>
|
||||
|
||||
<table border>
|
||||
<tr>
|
||||
<th>Parameter
|
||||
|
||||
<th>Description
|
||||
|
||||
<tr>
|
||||
<td><tt>BaseIterator</tt>
|
||||
|
||||
<td>The iterator type being wrapped. The <tt>value_type</tt>
|
||||
of the base iterator should itself be dereferenceable.
|
||||
The return type of the <tt>operator*</tt> for the
|
||||
<tt>value_type</tt> should match the <tt>Reference</tt> type.
|
||||
|
||||
<tr>
|
||||
<td><tt>Value</tt>
|
||||
|
||||
<td>The <tt>value_type</tt> of the resulting iterator, unless const. If
|
||||
Value is <tt>const X</tt>, a conforming compiler makes the
|
||||
<tt>value_type</tt> <tt><i>non-</i>const X</tt><a href=
|
||||
"iterator_adaptors.htm#1">[1]</a>. Note that if the default
|
||||
is used for <tt>Value</tt>, then there must be a valid specialization
|
||||
of <tt>iterator_traits</tt> for the value type of the base iterator.
|
||||
<br>
|
||||
<b>Default:</b> <tt>std::iterator_traits<<br>
|
||||
<20> std::iterator_traits<BaseIterator>::value_type
|
||||
>::value_type</tt><a href="#2">[2]</a>
|
||||
|
||||
<tr>
|
||||
<td><tt>Reference</tt>
|
||||
|
||||
<td>The <tt>reference</tt> type of the resulting iterator, and in
|
||||
particular, the result type of <tt>operator*()</tt>.<br>
|
||||
<b>Default:</b> <tt>Value&</tt>
|
||||
|
||||
<tr>
|
||||
<td><tt>Pointer</tt>
|
||||
|
||||
<td>The <tt>pointer</tt> type of the resulting iterator, and in
|
||||
particular, the result type of <tt>operator->()</tt>.<br>
|
||||
<b>Default:</b> <tt>Value*</tt>
|
||||
|
||||
<tr>
|
||||
<td><tt>Category</tt>
|
||||
<td>The <tt>iterator_category</tt> type for the resulting iterator.<br>
|
||||
<b>Default:</b>
|
||||
<tt>std::iterator_traits<BaseIterator>::iterator_category</tt>
|
||||
|
||||
</table>
|
||||
|
||||
<h3>Concept Model</h3>
|
||||
The indirect iterator will model whichever <a href=
|
||||
"http://www.sgi.com/tech/stl/Iterators.html">standard iterator
|
||||
concept category</a> is modeled by the base iterator. Thus, if the
|
||||
base iterator is a model of <a href=
|
||||
"http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random
|
||||
Access Iterator</a> then so is the resulting indirect iterator. If
|
||||
the base iterator models a more restrictive concept, the resulting
|
||||
indirect iterator will model the same concept <a href="#3">[3]</a>.
|
||||
|
||||
<h3>Members</h3>
|
||||
The indirect iterator type implements the member functions and operators
|
||||
required of the <a href=
|
||||
"http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access
|
||||
Iterator</a> concept. In addition it has the following constructor:
|
||||
<pre>
|
||||
explicit indirect_iterator_generator::type(const BaseIterator& it)
|
||||
</pre>
|
||||
<br>
|
||||
<br>
|
||||
|
||||
<hr>
|
||||
|
||||
<p>
|
||||
|
||||
<h2><a name="indirect_iterator_pair_generator">The Indirect Iterator Pair
|
||||
Generator</a></h2>
|
||||
Sometimes a pair of <tt>const</tt>/non-<tt>const</tt> pair of iterators is
|
||||
needed, such as when implementing a container. The
|
||||
<tt>indirect_iterator_pair_generator</tt> class makes it more convenient to
|
||||
create this pair of iterator types.
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
template <class BaseIterator,
|
||||
class Value, class Reference, class ConstReference,
|
||||
class Category, class Pointer, class ConstPointer>
|
||||
struct indirect_iterator_pair_generator;
|
||||
{
|
||||
public:
|
||||
typedef <tt><a href=
|
||||
"./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a><...></tt> iterator; // the mutable indirect iterator type
|
||||
typedef <tt><a href=
|
||||
"./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a><...></tt> const_iterator; // the immutable indirect iterator type
|
||||
};
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<h3>Example</h3>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
// continuing from the last example...
|
||||
|
||||
typedef boost::indirect_iterator_pair_generator<char**,
|
||||
char, char*, char&, const char*, const char&> PairGen;
|
||||
|
||||
char mutable_characters[N];
|
||||
char* pointers_to_mutable_chars[N];
|
||||
for (int i = 0; i < N; ++i)
|
||||
pointers_to_mutable_chars[i] = &mutable_characters[i];
|
||||
|
||||
PairGen::iterator mutable_indirect_first(pointers_to_mutable_chars),
|
||||
mutable_indirect_last(pointers_to_mutable_chars + N);
|
||||
PairGen::const_iterator const_indirect_first(pointers_to_chars),
|
||||
const_indirect_last(pointers_to_chars + N);
|
||||
|
||||
std::transform(const_indirect_first, const_indirect_last,
|
||||
mutable_indirect_first, std::bind1st(std::plus<char>(), 1));
|
||||
|
||||
std::copy(mutable_indirect_first, mutable_indirect_last,
|
||||
std::ostream_iterator<char>(std::cout, ","));
|
||||
std::cout << std::endl;
|
||||
// to be continued...
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>The output is:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
b,c,d,e,f,g,h,
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<h3>Template Parameters</h3>
|
||||
|
||||
<table border>
|
||||
<tr>
|
||||
<th>Parameter
|
||||
|
||||
<th>Description
|
||||
|
||||
<tr>
|
||||
<td><tt>BaseIterator</tt>
|
||||
|
||||
<td>The iterator type being wrapped. The <tt>value_type</tt> of the
|
||||
base iterator should itself be dereferenceable.
|
||||
The return type of the <tt>operator*</tt> for the
|
||||
<tt>value_type</tt> should match the <tt>Reference</tt> type.
|
||||
|
||||
<tr>
|
||||
<td><tt>Value</tt>
|
||||
|
||||
<td>The <tt>value_type</tt> of the resulting iterators.
|
||||
If Value is <tt>const X</tt>, a conforming compiler makes the
|
||||
<tt>value_type</tt> <tt><i>non-</i>const X</tt><a href=
|
||||
"iterator_adaptors.htm#1">[1]</a>. Note that if the default
|
||||
is used for <tt>Value</tt>, then there must be a valid
|
||||
specialization of <tt>iterator_traits</tt> for the value type
|
||||
of the base iterator.<br>
|
||||
|
||||
<b>Default:</b> <tt>std::iterator_traits<<br>
|
||||
<20> std::iterator_traits<BaseIterator>::value_type
|
||||
>::value_type</tt><a href="#2">[2]</a>
|
||||
|
||||
<tr>
|
||||
<td><tt>Reference</tt>
|
||||
|
||||
<td>The <tt>reference</tt> type of the resulting <tt>iterator</tt>, and
|
||||
in particular, the result type of its <tt>operator*()</tt>.<br>
|
||||
<b>Default:</b> <tt>Value&</tt>
|
||||
|
||||
<tr>
|
||||
<td><tt>ConstReference</tt>
|
||||
|
||||
<td>The <tt>reference</tt> type of the resulting
|
||||
<tt>const_iterator</tt>, and in particular, the result type of its
|
||||
<tt>operator*()</tt>.<br>
|
||||
<b>Default:</b> <tt>const Value&</tt>
|
||||
|
||||
<tr>
|
||||
<td><tt>Category</tt>
|
||||
<td>The <tt>iterator_category</tt> type for the resulting iterator.<br>
|
||||
<b>Default:</b>
|
||||
<tt>std::iterator_traits<BaseIterator>::iterator_category</tt>
|
||||
|
||||
<tr>
|
||||
<td><tt>Pointer</tt>
|
||||
|
||||
<td>The <tt>pointer</tt> type of the resulting <tt>iterator</tt>, and
|
||||
in particular, the result type of its <tt>operator->()</tt>.<br>
|
||||
<b>Default:</b> <tt>Value*</tt>
|
||||
|
||||
<tr>
|
||||
<td><tt>ConstPointer</tt>
|
||||
|
||||
<td>The <tt>pointer</tt> type of the resulting <tt>const_iterator</tt>,
|
||||
and in particular, the result type of its <tt>operator->()</tt>.<br>
|
||||
<b>Default:</b> <tt>const Value*</tt>
|
||||
|
||||
</table>
|
||||
|
||||
<h3>Concept Model</h3>
|
||||
|
||||
The indirect iterators will model whichever <a href=
|
||||
"http://www.sgi.com/tech/stl/Iterators.html">standard iterator
|
||||
concept category</a> is modeled by the base iterator. Thus, if the
|
||||
base iterator is a model of <a href=
|
||||
"http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random
|
||||
Access Iterator</a> then so are the resulting indirect
|
||||
iterators. If the base iterator models a more restrictive concept,
|
||||
the resulting indirect iterators will model the same concept <a
|
||||
href="#3">[3]</a>.
|
||||
|
||||
|
||||
<h3>Members</h3>
|
||||
The resulting <tt>iterator</tt> and <tt>const_iterator</tt> types implement
|
||||
the member functions and operators required of the <a href=
|
||||
"http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access
|
||||
Iterator</a> concept. In addition they support the following constructors:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
explicit indirect_iterator_pair_generator::iterator(const BaseIterator& it)
|
||||
explicit indirect_iterator_pair_generator::const_iterator(const BaseIterator& it)
|
||||
</pre>
|
||||
</blockquote>
|
||||
<br>
|
||||
<br>
|
||||
|
||||
<hr>
|
||||
|
||||
<p>
|
||||
|
||||
<h2><a name="make_indirect_iterator">The Indirect Iterator Object
|
||||
Generator</a></h2>
|
||||
The <tt>make_indirect_iterator()</tt> function provides a more convenient
|
||||
way to create indirect iterator objects. The function saves the user the
|
||||
trouble of explicitly writing out the iterator types.
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
template <class BaseIterator>
|
||||
typename indirect_iterator_generator<BaseIterator>::type
|
||||
make_indirect_iterator(BaseIterator base)
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<h3>Example</h3>
|
||||
Here we again print the <tt>char</tt>s from the array <tt>characters</tt>
|
||||
by accessing them through the array of pointers <tt>pointer_to_chars</tt>,
|
||||
but this time we use the <tt>make_indirect_iterator()</tt> function which
|
||||
saves us some typing.
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
// continuing from the last example...
|
||||
|
||||
std::copy(boost::make_indirect_iterator(pointers_to_chars),
|
||||
boost::make_indirect_iterator(pointers_to_chars + N),
|
||||
std::ostream_iterator<char>(std::cout, ","));
|
||||
std::cout << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
The output is:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
a,b,c,d,e,f,g,
|
||||
</pre>
|
||||
</blockquote>
|
||||
<hr>
|
||||
|
||||
<h3>Notes</h3>
|
||||
|
||||
<p>
|
||||
|
||||
<p><a name="2">[2]</a> If your compiler does not support partial
|
||||
specialization and the base iterator or its <tt>value_type</tt> is a
|
||||
builtin pointer type, you will not be able to use the default for
|
||||
<tt>Value</tt> and will need to specify this type explicitly.
|
||||
|
||||
<p><a name="3">[3]</a>There is a caveat to which concept the
|
||||
indirect iterator can model. If the return type of the
|
||||
<tt>operator*</tt> for the base iterator's value type is not a
|
||||
true reference, then strickly speaking, the indirect iterator can
|
||||
not be a model of <a href=
|
||||
"http://www.sgi.com/tech/stl/ForwardIterator.html">Forward
|
||||
Iterator</a> or any of the concepts that refine it. In this case
|
||||
the <tt>Category</tt> for the indirect iterator should be
|
||||
specified as <tt>std::input_iterator_tag</tt>. However, even in
|
||||
this case, if the base iterator is a random access iterator, the
|
||||
resulting indirect iterator will still satisfy most of the
|
||||
requirements for <a href=
|
||||
"http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random
|
||||
Access Iterator</a>.
|
||||
|
||||
<hr>
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->18 Sep 2001<!--webbot bot="Timestamp" endspan i-checksum="14941" -->
|
||||
|
||||
|
||||
<p>© Copyright Jeremy Siek and David Abrahams 2001. Permission to
|
||||
copy, use, modify, sell and distribute this document is granted provided
|
||||
this copyright notice appears in all copies. This document is provided "as
|
||||
is" without express or implied warranty, and with no claim as to its
|
||||
suitability for any purpose.
|
||||
<!-- LocalWords: html charset alt gif hpp BaseIterator const namespace struct
|
||||
-->
|
||||
|
||||
<!-- LocalWords: ConstPointer ConstReference typename iostream int abcdefg
|
||||
-->
|
||||
<!-- LocalWords: sizeof PairGen pre Jeremy Siek David Abrahams
|
||||
-->
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
@@ -1,59 +0,0 @@
|
||||
// (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <functional>
|
||||
#include <algorithm>
|
||||
#include <boost/iterator/indirect_iterator.hpp>
|
||||
|
||||
int main(int, char*[])
|
||||
{
|
||||
char characters[] = "abcdefg";
|
||||
const int N = sizeof(characters)/sizeof(char) - 1; // -1 since characters has a null char
|
||||
char* pointers_to_chars[N]; // at the end.
|
||||
for (int i = 0; i < N; ++i)
|
||||
pointers_to_chars[i] = &characters[i];
|
||||
|
||||
// Example of using indirect_iterator_generator
|
||||
|
||||
boost::indirect_iterator<char**, char>
|
||||
indirect_first(pointers_to_chars), indirect_last(pointers_to_chars + N);
|
||||
|
||||
std::copy(indirect_first, indirect_last, std::ostream_iterator<char>(std::cout, ","));
|
||||
std::cout << std::endl;
|
||||
|
||||
|
||||
// Example of using indirect_iterator_pair_generator
|
||||
|
||||
char mutable_characters[N];
|
||||
char* pointers_to_mutable_chars[N];
|
||||
for (int j = 0; j < N; ++j)
|
||||
pointers_to_mutable_chars[j] = &mutable_characters[j];
|
||||
|
||||
boost::indirect_iterator<char* const*> mutable_indirect_first(pointers_to_mutable_chars),
|
||||
mutable_indirect_last(pointers_to_mutable_chars + N);
|
||||
boost::indirect_iterator<char* const*, char const> const_indirect_first(pointers_to_chars),
|
||||
const_indirect_last(pointers_to_chars + N);
|
||||
|
||||
std::transform(const_indirect_first, const_indirect_last,
|
||||
mutable_indirect_first, std::bind1st(std::plus<char>(), 1));
|
||||
|
||||
std::copy(mutable_indirect_first, mutable_indirect_last,
|
||||
std::ostream_iterator<char>(std::cout, ","));
|
||||
std::cout << std::endl;
|
||||
|
||||
|
||||
// Example of using make_indirect_iterator()
|
||||
|
||||
std::copy(boost::make_indirect_iterator(pointers_to_chars),
|
||||
boost::make_indirect_iterator(pointers_to_chars + N),
|
||||
std::ostream_iterator<char>(std::cout, ","));
|
||||
std::cout << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
@@ -1,46 +0,0 @@
|
||||
// (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
|
||||
#include <functional>
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <boost/iterator/transform_iterator.hpp>
|
||||
#include <boost/pending/integer_range.hpp>
|
||||
|
||||
int
|
||||
main(int, char*[])
|
||||
{
|
||||
// This is a simple example of using the transform_iterators class to
|
||||
// generate iterators that multiply the value returned by dereferencing
|
||||
// the iterator. In this case we are multiplying by 2.
|
||||
// Would be cooler to use lambda library in this example.
|
||||
|
||||
int x[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
|
||||
|
||||
typedef std::binder1st< std::multiplies<int> > Function;
|
||||
|
||||
typedef boost::transform_iterator<Function, int*> doubling_iterator;
|
||||
|
||||
doubling_iterator i(x, std::bind1st(std::multiplies<int>(), 2)),
|
||||
i_end(x + sizeof(x)/sizeof(int), std::bind1st(std::multiplies<int>(), 2));
|
||||
|
||||
std::cout << "multiplying the array by 2:" << std::endl;
|
||||
while (i != i_end)
|
||||
std::cout << *i++ << " ";
|
||||
std::cout << std::endl;
|
||||
|
||||
// Here is an example of counting from 0 to 5 using the integer_range class.
|
||||
|
||||
boost::integer_range<int> r(0,5);
|
||||
|
||||
std::cout << "counting to from 0 to 4:" << std::endl;
|
||||
std::copy(r.begin(), r.end(), std::ostream_iterator<int>(std::cout, " "));
|
||||
std::cout << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
@@ -1,215 +0,0 @@
|
||||
// (C) Copyright David Abrahams 2002. Permission to copy, use, modify,
|
||||
// sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
|
||||
// See http://www.boost.org for most recent version including documentation.
|
||||
|
||||
// Revision History
|
||||
// 04 Mar 2001 Patches for Intel C++ (Dave Abrahams)
|
||||
// 19 Feb 2001 Take advantage of improved iterator_traits to do more tests
|
||||
// on MSVC. Reordered some #ifdefs for coherency.
|
||||
// (David Abrahams)
|
||||
// 13 Feb 2001 Test new VC6 workarounds (David Abrahams)
|
||||
// 11 Feb 2001 Final fixes for Borland (David Abrahams)
|
||||
// 11 Feb 2001 Some fixes for Borland get it closer on that compiler
|
||||
// (David Abrahams)
|
||||
// 07 Feb 2001 More comprehensive testing; factored out static tests for
|
||||
// better reuse (David Abrahams)
|
||||
// 21 Jan 2001 Quick fix to my_iterator, which wasn't returning a
|
||||
// reference type from operator* (David Abrahams)
|
||||
// 19 Jan 2001 Initial version with iterator operators (David Abrahams)
|
||||
|
||||
#include <boost/detail/iterator.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/operators.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
|
||||
// A UDT for which we can specialize std::iterator_traits<element*> on
|
||||
// compilers which don't support partial specialization. There's no
|
||||
// other reasonable way to test pointers on those compilers.
|
||||
struct element {};
|
||||
|
||||
// An iterator for which we can get traits.
|
||||
struct my_iterator1
|
||||
: boost::forward_iterator_helper<my_iterator1, char, long, const char*, const char&>
|
||||
{
|
||||
my_iterator1(const char* p) : m_p(p) {}
|
||||
|
||||
bool operator==(const my_iterator1& rhs) const
|
||||
{ return this->m_p == rhs.m_p; }
|
||||
|
||||
my_iterator1& operator++() { ++this->m_p; return *this; }
|
||||
const char& operator*() { return *m_p; }
|
||||
private:
|
||||
const char* m_p;
|
||||
};
|
||||
|
||||
// Used to prove that we don't require std::iterator<> in the hierarchy under
|
||||
// MSVC6, and that we can compute all the traits for a standard-conforming UDT
|
||||
// iterator.
|
||||
struct my_iterator2
|
||||
: boost::equality_comparable<my_iterator2
|
||||
, boost::incrementable<my_iterator2
|
||||
, boost::dereferenceable<my_iterator2,const char*> > >
|
||||
{
|
||||
typedef char value_type;
|
||||
typedef long difference_type;
|
||||
typedef const char* pointer;
|
||||
typedef const char& reference;
|
||||
typedef std::forward_iterator_tag iterator_category;
|
||||
|
||||
my_iterator2(const char* p) : m_p(p) {}
|
||||
|
||||
bool operator==(const my_iterator2& rhs) const
|
||||
{ return this->m_p == rhs.m_p; }
|
||||
|
||||
my_iterator2& operator++() { ++this->m_p; return *this; }
|
||||
const char& operator*() { return *m_p; }
|
||||
private:
|
||||
const char* m_p;
|
||||
};
|
||||
|
||||
// Used to prove that we're not overly confused by the existence of
|
||||
// std::iterator<> in the hierarchy under MSVC6 - we should find that
|
||||
// boost::detail::iterator_traits<my_iterator3>::difference_type is int.
|
||||
struct my_iterator3 : my_iterator1
|
||||
{
|
||||
typedef int difference_type;
|
||||
my_iterator3(const char* p)
|
||||
: my_iterator1(p) {}
|
||||
};
|
||||
|
||||
//
|
||||
// Assertion tools. Used instead of BOOST_STATIC_ASSERT because that
|
||||
// doesn't give us a nice stack backtrace
|
||||
//
|
||||
template <bool = false> struct assertion;
|
||||
|
||||
template <> struct assertion<true>
|
||||
{
|
||||
typedef char type;
|
||||
};
|
||||
|
||||
template <class T, class U>
|
||||
struct assert_same
|
||||
: assertion<(::boost::is_same<T,U>::value)>
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
// Iterator tests
|
||||
template <class Iterator,
|
||||
class value_type, class difference_type, class pointer, class reference, class category>
|
||||
struct non_portable_tests
|
||||
{
|
||||
typedef typename boost::detail::iterator_traits<Iterator>::pointer test_pt;
|
||||
typedef typename boost::detail::iterator_traits<Iterator>::reference test_rt;
|
||||
typedef typename assert_same<test_pt, pointer>::type a1;
|
||||
typedef typename assert_same<test_rt, reference>::type a2;
|
||||
};
|
||||
|
||||
template <class Iterator,
|
||||
class value_type, class difference_type, class pointer, class reference, class category>
|
||||
struct portable_tests
|
||||
{
|
||||
typedef typename boost::detail::iterator_traits<Iterator>::difference_type test_dt;
|
||||
typedef typename boost::detail::iterator_traits<Iterator>::iterator_category test_cat;
|
||||
typedef typename assert_same<test_dt, difference_type>::type a1;
|
||||
typedef typename assert_same<test_cat, category>::type a2;
|
||||
};
|
||||
|
||||
// Test iterator_traits
|
||||
template <class Iterator,
|
||||
class value_type, class difference_type, class pointer, class reference, class category>
|
||||
struct input_iterator_test
|
||||
: portable_tests<Iterator,value_type,difference_type,pointer,reference,category>
|
||||
{
|
||||
typedef typename boost::detail::iterator_traits<Iterator>::value_type test_vt;
|
||||
typedef typename assert_same<test_vt, value_type>::type a1;
|
||||
};
|
||||
|
||||
template <class Iterator,
|
||||
class value_type, class difference_type, class pointer, class reference, class category>
|
||||
struct non_pointer_test
|
||||
: input_iterator_test<Iterator,value_type,difference_type,pointer,reference,category>
|
||||
, non_portable_tests<Iterator,value_type,difference_type,pointer,reference,category>
|
||||
{
|
||||
};
|
||||
|
||||
template <class Iterator,
|
||||
class value_type, class difference_type, class pointer, class reference, class category>
|
||||
struct maybe_pointer_test
|
||||
: portable_tests<Iterator,value_type,difference_type,pointer,reference,category>
|
||||
, non_portable_tests<Iterator,value_type,difference_type,pointer,reference,category>
|
||||
{
|
||||
};
|
||||
|
||||
input_iterator_test<std::istream_iterator<int>, int, std::ptrdiff_t, int*, int&, std::input_iterator_tag>
|
||||
istream_iterator_test;
|
||||
|
||||
#if defined(__BORLANDC__) && !defined(__SGI_STL_PORT)
|
||||
typedef ::std::char_traits<char>::off_type distance;
|
||||
non_pointer_test<std::ostream_iterator<int>,int,
|
||||
distance,int*,int&,std::output_iterator_tag> ostream_iterator_test;
|
||||
#elif defined(BOOST_MSVC_STD_ITERATOR)
|
||||
non_pointer_test<std::ostream_iterator<int>,
|
||||
int, void, int*, int&, std::output_iterator_tag>
|
||||
ostream_iterator_test;
|
||||
#else
|
||||
non_pointer_test<std::ostream_iterator<int>,
|
||||
void, void, void, void, std::output_iterator_tag>
|
||||
ostream_iterator_test;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __KCC
|
||||
typedef long std_list_diff_type;
|
||||
#else
|
||||
typedef std::ptrdiff_t std_list_diff_type;
|
||||
#endif
|
||||
|
||||
non_pointer_test<std::list<int>::iterator, int, std_list_diff_type, int*, int&, std::bidirectional_iterator_tag>
|
||||
list_iterator_test;
|
||||
|
||||
maybe_pointer_test<std::vector<int>::iterator, int, std::ptrdiff_t, int*, int&, std::random_access_iterator_tag>
|
||||
vector_iterator_test;
|
||||
|
||||
maybe_pointer_test<int*, int, std::ptrdiff_t, int*, int&, std::random_access_iterator_tag>
|
||||
int_pointer_test;
|
||||
|
||||
non_pointer_test<my_iterator1, char, long, const char*, const char&, std::forward_iterator_tag>
|
||||
my_iterator1_test;
|
||||
|
||||
non_pointer_test<my_iterator2, char, long, const char*, const char&, std::forward_iterator_tag>
|
||||
my_iterator2_test;
|
||||
|
||||
non_pointer_test<my_iterator3, char, int, const char*, const char&, std::forward_iterator_tag>
|
||||
my_iterator3_test;
|
||||
|
||||
int main()
|
||||
{
|
||||
char chars[100];
|
||||
int ints[100];
|
||||
|
||||
for (int length = 3; length < 100; length += length / 3)
|
||||
{
|
||||
std::list<int> l(length);
|
||||
assert(boost::detail::distance(l.begin(), l.end()) == length);
|
||||
|
||||
std::vector<int> v(length);
|
||||
assert(boost::detail::distance(v.begin(), v.end()) == length);
|
||||
|
||||
assert(boost::detail::distance(&ints[0], ints + length) == length);
|
||||
assert(boost::detail::distance(my_iterator1(chars), my_iterator1(chars + length)) == length);
|
||||
assert(boost::detail::distance(my_iterator2(chars), my_iterator2(chars + length)) == length);
|
||||
assert(boost::detail::distance(my_iterator3(chars), my_iterator3(chars + length)) == length);
|
||||
}
|
||||
return 0;
|
||||
}
|
@@ -1,10 +1,9 @@
|
||||
// Demonstrate and test boost/operators.hpp on std::iterators --------------//
|
||||
|
||||
// (C) Copyright Jeremy Siek 1999. Permission to copy, use, modify,
|
||||
// sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
// (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.
|
||||
|
||||
@@ -24,7 +23,7 @@
|
||||
#include <cstring> // for std::strcmp
|
||||
#include <iostream> // for std::cout (std::endl, ends, and flush indirectly)
|
||||
#include <string> // for std::string
|
||||
#include <strstream> // for std::ostrstream
|
||||
#include <sstream> // for std::stringstream
|
||||
|
||||
# ifdef BOOST_NO_STDC_NAMESPACE
|
||||
namespace std { using ::strcmp; }
|
||||
@@ -65,20 +64,16 @@ class test_opr_base
|
||||
protected:
|
||||
// Test data and types
|
||||
BOOST_STATIC_CONSTANT( std::size_t, fruit_length = 6u );
|
||||
BOOST_STATIC_CONSTANT( std::size_t, scratch_length = 40u );
|
||||
|
||||
typedef std::string fruit_array_type[ fruit_length ];
|
||||
typedef char scratch_array_type[ scratch_length ];
|
||||
|
||||
static fruit_array_type fruit;
|
||||
static scratch_array_type scratch;
|
||||
|
||||
}; // 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;
|
||||
const std::size_t test_opr_base::scratch_length;
|
||||
#endif
|
||||
|
||||
template <typename T, typename R = T&, typename P = T*>
|
||||
@@ -120,9 +115,6 @@ private:
|
||||
test_opr_base::fruit_array_type
|
||||
test_opr_base::fruit = { "apple", "orange", "pear", "peach", "grape", "plum" };
|
||||
|
||||
test_opr_base::scratch_array_type
|
||||
test_opr_base::scratch = "";
|
||||
|
||||
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 );
|
||||
@@ -176,15 +168,13 @@ test_opr<T, R, P>::post_increment_test
|
||||
{
|
||||
std::cout << "\tDoing post-increment test." << std::endl;
|
||||
|
||||
std::ostrstream oss( scratch, scratch_length );
|
||||
std::stringstream oss;
|
||||
for ( iter_type i = fruit_begin ; i != fruit_end ; )
|
||||
{
|
||||
oss << *i++ << ' ';
|
||||
}
|
||||
|
||||
oss << std::ends;
|
||||
BOOST_TEST( std::strcmp(oss.str(), "apple orange pear peach grape plum ")
|
||||
== 0 );
|
||||
BOOST_CHECK( oss.str() == "apple orange pear peach grape plum ");
|
||||
}
|
||||
|
||||
// Test post-decrement
|
||||
@@ -196,16 +186,14 @@ test_opr<T, R, P>::post_decrement_test
|
||||
{
|
||||
std::cout << "\tDoing post-decrement test." << std::endl;
|
||||
|
||||
std::ostrstream oss( scratch, scratch_length );
|
||||
std::stringstream oss;
|
||||
for ( iter_type i = fruit_end ; i != fruit_begin ; )
|
||||
{
|
||||
i--;
|
||||
oss << *i << ' ';
|
||||
}
|
||||
|
||||
oss << std::ends;
|
||||
BOOST_TEST( std::strcmp(oss.str(), "plum grape peach pear orange apple ")
|
||||
== 0 );
|
||||
BOOST_CHECK( oss.str() == "plum grape peach pear orange apple ");
|
||||
}
|
||||
|
||||
// Test indirect structure referral
|
||||
@@ -217,14 +205,13 @@ test_opr<T, R, P>::indirect_referral_test
|
||||
{
|
||||
std::cout << "\tDoing indirect reference test." << std::endl;
|
||||
|
||||
std::ostrstream oss( scratch, scratch_length );
|
||||
std::stringstream oss;
|
||||
for ( iter_type i = fruit_begin ; i != fruit_end ; ++i )
|
||||
{
|
||||
oss << i->size() << ' ';
|
||||
}
|
||||
|
||||
oss << std::ends;
|
||||
BOOST_TEST( std::strcmp(oss.str(), "5 6 4 5 5 4 ") == 0 );
|
||||
BOOST_CHECK( oss.str() == "5 6 4 5 5 4 ");
|
||||
}
|
||||
|
||||
// Test offset addition
|
||||
@@ -237,14 +224,13 @@ test_opr<T, R, P>::offset_addition_test
|
||||
std::cout << "\tDoing offset addition test." << std::endl;
|
||||
|
||||
std::ptrdiff_t const two = 2;
|
||||
std::ostrstream oss( scratch, scratch_length );
|
||||
std::stringstream oss;
|
||||
for ( iter_type i = fruit_begin ; i != fruit_end ; i = i + two )
|
||||
{
|
||||
oss << *i << ' ';
|
||||
}
|
||||
|
||||
oss << std::ends;
|
||||
BOOST_TEST( std::strcmp(oss.str(), "apple pear grape ") == 0 );
|
||||
BOOST_CHECK( oss.str() == "apple pear grape ");
|
||||
}
|
||||
|
||||
// Test offset addition, in reverse order
|
||||
@@ -257,14 +243,13 @@ 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::ostrstream oss( scratch, scratch_length );
|
||||
std::stringstream oss;
|
||||
for ( iter_type i = fruit_begin ; i != fruit_end ; i = two + i )
|
||||
{
|
||||
oss << *i << ' ';
|
||||
}
|
||||
|
||||
oss << std::ends;
|
||||
BOOST_TEST( std::strcmp(oss.str(), "apple pear grape ") == 0 );
|
||||
BOOST_CHECK( oss.str() == "apple pear grape ");
|
||||
}
|
||||
|
||||
// Test offset subtraction
|
||||
@@ -277,7 +262,7 @@ test_opr<T, R, P>::offset_subtraction_test
|
||||
std::cout << "\tDoing offset subtraction test." << std::endl;
|
||||
|
||||
std::ptrdiff_t const two = 2;
|
||||
std::ostrstream oss( scratch, scratch_length );
|
||||
std::stringstream oss;
|
||||
for ( iter_type i = fruit_end ; fruit_begin < i ; )
|
||||
{
|
||||
i = i - two;
|
||||
@@ -287,8 +272,7 @@ test_opr<T, R, P>::offset_subtraction_test
|
||||
}
|
||||
}
|
||||
|
||||
oss << std::ends;
|
||||
BOOST_TEST( std::strcmp(oss.str(), "grape pear apple ") == 0 );
|
||||
BOOST_CHECK( oss.str() == "grape pear apple ");
|
||||
}
|
||||
|
||||
// Test comparisons
|
||||
@@ -312,10 +296,10 @@ test_opr<T, R, P>::comparison_test
|
||||
{
|
||||
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) );
|
||||
BOOST_CHECK( (i != j) == (i_offset != j_offset) );
|
||||
BOOST_CHECK( (i > j) == (i_offset > j_offset) );
|
||||
BOOST_CHECK( (i <= j) == (i_offset <= j_offset) );
|
||||
BOOST_CHECK( (i >= j) == (i_offset >= j_offset) );
|
||||
}
|
||||
}
|
||||
cout << std::endl;
|
||||
@@ -330,13 +314,11 @@ test_opr<T, R, P>::indexing_test
|
||||
{
|
||||
std::cout << "\tDoing indexing test." << std::endl;
|
||||
|
||||
std::ostrstream oss( scratch, scratch_length );
|
||||
std::stringstream oss;
|
||||
for ( std::size_t k = 0u ; k < fruit_length ; ++k )
|
||||
{
|
||||
oss << fruit_begin[ k ] << ' ';
|
||||
}
|
||||
|
||||
oss << std::ends;
|
||||
BOOST_TEST( std::strcmp(oss.str(), "apple orange pear peach grape plum ")
|
||||
== 0 );
|
||||
BOOST_CHECK( oss.str() == "apple orange pear peach grape plum ");
|
||||
}
|
||||
|
@@ -1,10 +1,8 @@
|
||||
// boost class noncopyable test program ------------------------------------//
|
||||
|
||||
// (C) Copyright boost.org 1999. Permission to copy, use, modify, sell
|
||||
// and distribute this software is granted provided this copyright
|
||||
// notice appears in all copies. This software is provided "as is" without
|
||||
// express or implied warranty, and with no claim as to its suitability for
|
||||
// any purpose.
|
||||
// (C) 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 for most recent version including documentation.
|
||||
|
||||
|
@@ -1,8 +1,7 @@
|
||||
// (C) Copyright David Abrahams 2001. Permission to copy, use, modify,
|
||||
// sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
// (C) Copyright David Abrahams 2001.
|
||||
// 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.
|
||||
|
||||
@@ -58,14 +57,22 @@ struct complement
|
||||
struct traits
|
||||
{
|
||||
private:
|
||||
// indirection through complement_traits_aux neccessary to keep MSVC happy
|
||||
// indirection through complement_traits_aux necessary to keep MSVC happy
|
||||
typedef complement_traits_aux<Number, size - 1> prev;
|
||||
public:
|
||||
#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 0 && __GNUC_PATCHLEVEL__ == 2
|
||||
// GCC 4.0.2 ICEs on these C-style casts
|
||||
BOOST_STATIC_CONSTANT(Number, max =
|
||||
Number((prev::max) << CHAR_BIT)
|
||||
+ Number(UCHAR_MAX));
|
||||
BOOST_STATIC_CONSTANT(Number, min = Number((prev::min) << CHAR_BIT));
|
||||
#else
|
||||
BOOST_STATIC_CONSTANT(Number, max =
|
||||
Number(Number(prev::max) << CHAR_BIT)
|
||||
+ Number(UCHAR_MAX));
|
||||
|
||||
BOOST_STATIC_CONSTANT(Number, min = Number(Number(prev::min) << CHAR_BIT));
|
||||
#endif
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
@@ -222,10 +229,16 @@ void test_aux(unsigned_tag, Number*)
|
||||
(sizeof(Number) < sizeof(boost::intmax_t))
|
||||
| (boost::is_same<difference_type, boost::intmax_t>::value));
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 0 && __GNUC_PATCHLEVEL__ == 2
|
||||
// GCC 4.0.2 ICEs on this C-style cases
|
||||
BOOST_STATIC_ASSERT((complement_traits<Number>::max) > Number(0));
|
||||
BOOST_STATIC_ASSERT((complement_traits<Number>::min) == Number(0));
|
||||
#else
|
||||
// Force casting to Number here to work around the fact that it's an enum on MSVC
|
||||
BOOST_STATIC_ASSERT(Number(complement_traits<Number>::max) > Number(0));
|
||||
BOOST_STATIC_ASSERT(Number(complement_traits<Number>::min) == Number(0));
|
||||
|
||||
#endif
|
||||
|
||||
const Number max = complement_traits<Number>::max;
|
||||
const Number min = complement_traits<Number>::min;
|
||||
|
||||
@@ -309,10 +322,15 @@ void test_aux(signed_tag, Number*)
|
||||
(sizeof(Number) < sizeof(boost::intmax_t))
|
||||
| (boost::is_same<difference_type, Number>::value));
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 0 && __GNUC_PATCHLEVEL__ == 2
|
||||
// GCC 4.0.2 ICEs on this cast
|
||||
BOOST_STATIC_ASSERT((complement_traits<Number>::max) > Number(0));
|
||||
BOOST_STATIC_ASSERT((complement_traits<Number>::min) < Number(0));
|
||||
#else
|
||||
// Force casting to Number here to work around the fact that it's an enum on MSVC
|
||||
BOOST_STATIC_ASSERT(Number(complement_traits<Number>::max) > Number(0));
|
||||
BOOST_STATIC_ASSERT(Number(complement_traits<Number>::min) < Number(0));
|
||||
|
||||
#endif
|
||||
const Number max = complement_traits<Number>::max;
|
||||
const Number min = complement_traits<Number>::min;
|
||||
|
||||
@@ -375,8 +393,8 @@ int main()
|
||||
test<long>();
|
||||
test<unsigned long>();
|
||||
#if defined(BOOST_HAS_LONG_LONG) && !defined(BOOST_NO_INTEGRAL_INT64_T)
|
||||
test<long long>();
|
||||
test<unsigned long long>();
|
||||
test< ::boost::long_long_type>();
|
||||
test< ::boost::ulong_long_type>();
|
||||
#elif defined(BOOST_MSVC)
|
||||
// The problem of not having compile-time static class constants other than
|
||||
// enums prevents this from working, since values get truncated.
|
||||
|
@@ -10,7 +10,7 @@
|
||||
</head>
|
||||
|
||||
<body text="black" bgcolor="white" link="blue" vlink="purple" alink="red">
|
||||
<h1><img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align=
|
||||
<h1><img src="../../boost.png" alt="boost.png (6897 bytes)" align=
|
||||
"middle" width="277" height="86">Header <cite><<a href=
|
||||
"../../boost/operators.hpp">boost/operators.hpp</a>></cite></h1>
|
||||
|
||||
@@ -1955,7 +1955,7 @@ T operator+( T lhs, const T& rhs )
|
||||
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=
|
||||
"function_output_iterator.htm">boost::function_output_iterator</a></code>
|
||||
"../iterator/doc/function_output_iterator.html">boost::function_output_iterator</a></code>
|
||||
adaptor:</p>
|
||||
<pre>
|
||||
template<class UnaryFunction>
|
||||
@@ -2119,10 +2119,10 @@ public:
|
||||
backward-compatible.</p>
|
||||
<hr>
|
||||
|
||||
<p>Revised: 03 Dec 2003</p>
|
||||
<p>Revised: 29 Oct 2004</p>
|
||||
|
||||
<p>Copyright © Beman Dawes, David Abrahams, 1999-2001.</p>
|
||||
<p>Copyright © Daniel Frey, 2002-2003.</p>
|
||||
<p>Copyright © Daniel Frey, 2002-2004.</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
|
||||
|
@@ -1,7 +1,8 @@
|
||||
// Demonstrate and test boost/operators.hpp -------------------------------//
|
||||
|
||||
// Copyright Beman Dawes 1999.
|
||||
// See accompanying license for terms and conditions of use.
|
||||
// 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.
|
||||
|
||||
@@ -268,17 +269,17 @@ namespace
|
||||
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) );
|
||||
BOOST_CHECK( true_value(y1) == true_value(y2) );
|
||||
BOOST_CHECK( 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( (x1 < y1) == (x2 < y2) );
|
||||
BOOST_TEST( (x1 <= y1) == (x2 <= y2) );
|
||||
BOOST_TEST( (x1 >= y1) == (x2 >= y2) );
|
||||
BOOST_TEST( (x1 > y1) == (x2 > y2) );
|
||||
BOOST_CHECK( (x1 < y1) == (x2 < y2) );
|
||||
BOOST_CHECK( (x1 <= y1) == (x2 <= y2) );
|
||||
BOOST_CHECK( (x1 >= y1) == (x2 >= y2) );
|
||||
BOOST_CHECK( (x1 > y1) == (x2 > y2) );
|
||||
}
|
||||
|
||||
template <class X1, class Y1, class X2, class Y2>
|
||||
@@ -292,8 +293,8 @@ namespace
|
||||
template <class X1, class Y1, class X2, class Y2>
|
||||
void test_equality_comparable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
||||
{
|
||||
BOOST_TEST( (x1 == y1) == (x2 == y2) );
|
||||
BOOST_TEST( (x1 != y1) == (x2 != y2) );
|
||||
BOOST_CHECK( (x1 == y1) == (x2 == y2) );
|
||||
BOOST_CHECK( (x1 != y1) == (x2 != y2) );
|
||||
}
|
||||
|
||||
template <class X1, class Y1, class X2, class Y2>
|
||||
@@ -307,7 +308,7 @@ namespace
|
||||
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) );
|
||||
BOOST_CHECK( (x1 * y1).value() == (x2 * y2) );
|
||||
}
|
||||
|
||||
template <class X1, class Y1, class X2, class Y2>
|
||||
@@ -321,7 +322,7 @@ namespace
|
||||
template <class A, class B>
|
||||
void test_value_equality(A a, B b)
|
||||
{
|
||||
BOOST_TEST(a.value() == b);
|
||||
BOOST_CHECK(a.value() == b);
|
||||
}
|
||||
|
||||
#define TEST_OP_R(op) test_value_equality(x1 op y1, x2 op y2)
|
||||
@@ -447,16 +448,16 @@ namespace
|
||||
void test_incrementable(X1 x1, X2 x2)
|
||||
{
|
||||
sanity_check( x1, x1, x2, x2 );
|
||||
BOOST_TEST( (x1++).value() == x2++ );
|
||||
BOOST_TEST( x1.value() == x2 );
|
||||
BOOST_CHECK( (x1++).value() == x2++ );
|
||||
BOOST_CHECK( 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 );
|
||||
BOOST_CHECK( (x1--).value() == x2-- );
|
||||
BOOST_CHECK( x1.value() == x2 );
|
||||
}
|
||||
|
||||
template <class X1, class Y1, class X2, class Y2>
|
||||
@@ -560,7 +561,7 @@ template Wrapped6<unsigned long, unsigned char>;
|
||||
template Wrapped6<unsigned int, unsigned char>;
|
||||
#endif
|
||||
|
||||
#define PRIVATE_EXPR_TEST(e, t) BOOST_TEST( ((e), (t)) )
|
||||
#define PRIVATE_EXPR_TEST(e, t) BOOST_CHECK( ((e), (t)) )
|
||||
|
||||
int
|
||||
test_main( int , char * [] )
|
||||
@@ -605,22 +606,22 @@ test_main( int , char * [] )
|
||||
MyInt i2(2);
|
||||
MyInt i;
|
||||
|
||||
BOOST_TEST( i1.value() == 1 );
|
||||
BOOST_TEST( i2.value() == 2 );
|
||||
BOOST_TEST( i.value() == 0 );
|
||||
BOOST_CHECK( i1.value() == 1 );
|
||||
BOOST_CHECK( i2.value() == 2 );
|
||||
BOOST_CHECK( i.value() == 0 );
|
||||
|
||||
cout << "Created MyInt objects.\n";
|
||||
|
||||
PRIVATE_EXPR_TEST( (i = i2), (i.value() == 2) );
|
||||
|
||||
BOOST_TEST( i2 == i );
|
||||
BOOST_TEST( i1 != i2 );
|
||||
BOOST_TEST( i1 < i2 );
|
||||
BOOST_TEST( i1 <= i2 );
|
||||
BOOST_TEST( i <= i2 );
|
||||
BOOST_TEST( i2 > i1 );
|
||||
BOOST_TEST( i2 >= i1 );
|
||||
BOOST_TEST( i2 >= i );
|
||||
BOOST_CHECK( i2 == i );
|
||||
BOOST_CHECK( i1 != i2 );
|
||||
BOOST_CHECK( i1 < i2 );
|
||||
BOOST_CHECK( i1 <= i2 );
|
||||
BOOST_CHECK( i <= i2 );
|
||||
BOOST_CHECK( i2 > i1 );
|
||||
BOOST_CHECK( i2 >= i1 );
|
||||
BOOST_CHECK( i2 >= i );
|
||||
|
||||
PRIVATE_EXPR_TEST( (i = i1 + i2), (i.value() == 3) );
|
||||
PRIVATE_EXPR_TEST( (i = i + i2), (i.value() == 5) );
|
||||
@@ -644,86 +645,86 @@ test_main( int , char * [] )
|
||||
MyLong j2(2);
|
||||
MyLong j;
|
||||
|
||||
BOOST_TEST( j1.value() == 1 );
|
||||
BOOST_TEST( j2.value() == 2 );
|
||||
BOOST_TEST( j.value() == 0 );
|
||||
BOOST_CHECK( j1.value() == 1 );
|
||||
BOOST_CHECK( j2.value() == 2 );
|
||||
BOOST_CHECK( j.value() == 0 );
|
||||
|
||||
cout << "Created MyLong objects.\n";
|
||||
|
||||
PRIVATE_EXPR_TEST( (j = j2), (j.value() == 2) );
|
||||
|
||||
BOOST_TEST( j2 == j );
|
||||
BOOST_TEST( 2 == j );
|
||||
BOOST_TEST( j2 == 2 );
|
||||
BOOST_TEST( j == j2 );
|
||||
BOOST_TEST( j1 != j2 );
|
||||
BOOST_TEST( j1 != 2 );
|
||||
BOOST_TEST( 1 != j2 );
|
||||
BOOST_TEST( j1 < j2 );
|
||||
BOOST_TEST( 1 < j2 );
|
||||
BOOST_TEST( j1 < 2 );
|
||||
BOOST_TEST( j1 <= j2 );
|
||||
BOOST_TEST( 1 <= j2 );
|
||||
BOOST_TEST( j1 <= j );
|
||||
BOOST_TEST( j <= j2 );
|
||||
BOOST_TEST( 2 <= j2 );
|
||||
BOOST_TEST( j <= 2 );
|
||||
BOOST_TEST( j2 > j1 );
|
||||
BOOST_TEST( 2 > j1 );
|
||||
BOOST_TEST( j2 > 1 );
|
||||
BOOST_TEST( j2 >= j1 );
|
||||
BOOST_TEST( 2 >= j1 );
|
||||
BOOST_TEST( j2 >= 1 );
|
||||
BOOST_TEST( j2 >= j );
|
||||
BOOST_TEST( 2 >= j );
|
||||
BOOST_TEST( j2 >= 2 );
|
||||
BOOST_CHECK( j2 == j );
|
||||
BOOST_CHECK( 2 == j );
|
||||
BOOST_CHECK( j2 == 2 );
|
||||
BOOST_CHECK( j == j2 );
|
||||
BOOST_CHECK( j1 != j2 );
|
||||
BOOST_CHECK( j1 != 2 );
|
||||
BOOST_CHECK( 1 != j2 );
|
||||
BOOST_CHECK( j1 < j2 );
|
||||
BOOST_CHECK( 1 < j2 );
|
||||
BOOST_CHECK( j1 < 2 );
|
||||
BOOST_CHECK( j1 <= j2 );
|
||||
BOOST_CHECK( 1 <= j2 );
|
||||
BOOST_CHECK( j1 <= j );
|
||||
BOOST_CHECK( j <= j2 );
|
||||
BOOST_CHECK( 2 <= j2 );
|
||||
BOOST_CHECK( j <= 2 );
|
||||
BOOST_CHECK( j2 > j1 );
|
||||
BOOST_CHECK( 2 > j1 );
|
||||
BOOST_CHECK( j2 > 1 );
|
||||
BOOST_CHECK( j2 >= j1 );
|
||||
BOOST_CHECK( 2 >= j1 );
|
||||
BOOST_CHECK( j2 >= 1 );
|
||||
BOOST_CHECK( j2 >= j );
|
||||
BOOST_CHECK( 2 >= j );
|
||||
BOOST_CHECK( j2 >= 2 );
|
||||
|
||||
BOOST_TEST( (j1 + 2) == 3 );
|
||||
BOOST_TEST( (1 + j2) == 3 );
|
||||
BOOST_CHECK( (j1 + 2) == 3 );
|
||||
BOOST_CHECK( (1 + j2) == 3 );
|
||||
PRIVATE_EXPR_TEST( (j = j1 + j2), (j.value() == 3) );
|
||||
|
||||
BOOST_TEST( (j + 2) == 5 );
|
||||
BOOST_TEST( (3 + j2) == 5 );
|
||||
BOOST_CHECK( (j + 2) == 5 );
|
||||
BOOST_CHECK( (3 + j2) == 5 );
|
||||
PRIVATE_EXPR_TEST( (j = j + j2), (j.value() == 5) );
|
||||
|
||||
BOOST_TEST( (j - 1) == 4 );
|
||||
BOOST_CHECK( (j - 1) == 4 );
|
||||
PRIVATE_EXPR_TEST( (j = j - j1), (j.value() == 4) );
|
||||
|
||||
BOOST_TEST( (j * 2) == 8 );
|
||||
BOOST_TEST( (4 * j2) == 8 );
|
||||
BOOST_CHECK( (j * 2) == 8 );
|
||||
BOOST_CHECK( (4 * j2) == 8 );
|
||||
PRIVATE_EXPR_TEST( (j = j * j2), (j.value() == 8) );
|
||||
|
||||
BOOST_TEST( (j / 2) == 4 );
|
||||
BOOST_CHECK( (j / 2) == 4 );
|
||||
PRIVATE_EXPR_TEST( (j = j / j2), (j.value() == 4) );
|
||||
|
||||
BOOST_TEST( (j % 3) == 1 );
|
||||
BOOST_CHECK( (j % 3) == 1 );
|
||||
PRIVATE_EXPR_TEST( (j = j % ( j - j1 )), (j.value() == 1) );
|
||||
|
||||
PRIVATE_EXPR_TEST( (j = j2 + j2), (j.value() == 4) );
|
||||
|
||||
BOOST_TEST( (1 | j2 | j) == 7 );
|
||||
BOOST_TEST( (j1 | 2 | j) == 7 );
|
||||
BOOST_TEST( (j1 | j2 | 4) == 7 );
|
||||
BOOST_CHECK( (1 | j2 | j) == 7 );
|
||||
BOOST_CHECK( (j1 | 2 | j) == 7 );
|
||||
BOOST_CHECK( (j1 | j2 | 4) == 7 );
|
||||
PRIVATE_EXPR_TEST( (j = j1 | j2 | j), (j.value() == 7) );
|
||||
|
||||
BOOST_TEST( (7 & j2) == 2 );
|
||||
BOOST_TEST( (j & 2) == 2 );
|
||||
BOOST_CHECK( (7 & j2) == 2 );
|
||||
BOOST_CHECK( (j & 2) == 2 );
|
||||
PRIVATE_EXPR_TEST( (j = j & j2), (j.value() == 2) );
|
||||
|
||||
PRIVATE_EXPR_TEST( (j = j | j1), (j.value() == 3) );
|
||||
|
||||
BOOST_TEST( (3 ^ j1) == 2 );
|
||||
BOOST_TEST( (j ^ 1) == 2 );
|
||||
BOOST_CHECK( (3 ^ j1) == 2 );
|
||||
BOOST_CHECK( (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( (j1 << 2) == 4 );
|
||||
BOOST_TEST( (j2 << 1) == 4 );
|
||||
BOOST_CHECK( (j1 << 2) == 4 );
|
||||
BOOST_CHECK( (j2 << 1) == 4 );
|
||||
PRIVATE_EXPR_TEST( (j = j1 << j2), (j.value() == 4) );
|
||||
|
||||
BOOST_TEST( (j >> 2) == 1 );
|
||||
BOOST_TEST( (j2 >> 1) == 1 );
|
||||
BOOST_CHECK( (j >> 2) == 1 );
|
||||
BOOST_CHECK( (j2 >> 1) == 1 );
|
||||
PRIVATE_EXPR_TEST( (j = j2 >> j1), (j.value() == 1) );
|
||||
|
||||
cout << "Performed tests on MyLong objects.\n";
|
||||
@@ -732,22 +733,22 @@ test_main( int , char * [] )
|
||||
MyChar k2(2);
|
||||
MyChar k;
|
||||
|
||||
BOOST_TEST( k1.value() == 1 );
|
||||
BOOST_TEST( k2.value() == 2 );
|
||||
BOOST_TEST( k.value() == 0 );
|
||||
BOOST_CHECK( k1.value() == 1 );
|
||||
BOOST_CHECK( k2.value() == 2 );
|
||||
BOOST_CHECK( k.value() == 0 );
|
||||
|
||||
cout << "Created MyChar objects.\n";
|
||||
|
||||
PRIVATE_EXPR_TEST( (k = k2), (k.value() == 2) );
|
||||
|
||||
BOOST_TEST( k2 == k );
|
||||
BOOST_TEST( k1 != k2 );
|
||||
BOOST_TEST( k1 < k2 );
|
||||
BOOST_TEST( k1 <= k2 );
|
||||
BOOST_TEST( k <= k2 );
|
||||
BOOST_TEST( k2 > k1 );
|
||||
BOOST_TEST( k2 >= k1 );
|
||||
BOOST_TEST( k2 >= k );
|
||||
BOOST_CHECK( k2 == k );
|
||||
BOOST_CHECK( k1 != k2 );
|
||||
BOOST_CHECK( k1 < k2 );
|
||||
BOOST_CHECK( k1 <= k2 );
|
||||
BOOST_CHECK( k <= k2 );
|
||||
BOOST_CHECK( k2 > k1 );
|
||||
BOOST_CHECK( k2 >= k1 );
|
||||
BOOST_CHECK( k2 >= k );
|
||||
|
||||
cout << "Performed tests on MyChar objects.\n";
|
||||
|
||||
@@ -755,39 +756,39 @@ test_main( int , char * [] )
|
||||
MyShort l2(2);
|
||||
MyShort l;
|
||||
|
||||
BOOST_TEST( l1.value() == 1 );
|
||||
BOOST_TEST( l2.value() == 2 );
|
||||
BOOST_TEST( l.value() == 0 );
|
||||
BOOST_CHECK( l1.value() == 1 );
|
||||
BOOST_CHECK( l2.value() == 2 );
|
||||
BOOST_CHECK( l.value() == 0 );
|
||||
|
||||
cout << "Created MyShort objects.\n";
|
||||
|
||||
PRIVATE_EXPR_TEST( (l = l2), (l.value() == 2) );
|
||||
|
||||
BOOST_TEST( l2 == l );
|
||||
BOOST_TEST( 2 == l );
|
||||
BOOST_TEST( l2 == 2 );
|
||||
BOOST_TEST( l == l2 );
|
||||
BOOST_TEST( l1 != l2 );
|
||||
BOOST_TEST( l1 != 2 );
|
||||
BOOST_TEST( 1 != l2 );
|
||||
BOOST_TEST( l1 < l2 );
|
||||
BOOST_TEST( 1 < l2 );
|
||||
BOOST_TEST( l1 < 2 );
|
||||
BOOST_TEST( l1 <= l2 );
|
||||
BOOST_TEST( 1 <= l2 );
|
||||
BOOST_TEST( l1 <= l );
|
||||
BOOST_TEST( l <= l2 );
|
||||
BOOST_TEST( 2 <= l2 );
|
||||
BOOST_TEST( l <= 2 );
|
||||
BOOST_TEST( l2 > l1 );
|
||||
BOOST_TEST( 2 > l1 );
|
||||
BOOST_TEST( l2 > 1 );
|
||||
BOOST_TEST( l2 >= l1 );
|
||||
BOOST_TEST( 2 >= l1 );
|
||||
BOOST_TEST( l2 >= 1 );
|
||||
BOOST_TEST( l2 >= l );
|
||||
BOOST_TEST( 2 >= l );
|
||||
BOOST_TEST( l2 >= 2 );
|
||||
BOOST_CHECK( l2 == l );
|
||||
BOOST_CHECK( 2 == l );
|
||||
BOOST_CHECK( l2 == 2 );
|
||||
BOOST_CHECK( l == l2 );
|
||||
BOOST_CHECK( l1 != l2 );
|
||||
BOOST_CHECK( l1 != 2 );
|
||||
BOOST_CHECK( 1 != l2 );
|
||||
BOOST_CHECK( l1 < l2 );
|
||||
BOOST_CHECK( 1 < l2 );
|
||||
BOOST_CHECK( l1 < 2 );
|
||||
BOOST_CHECK( l1 <= l2 );
|
||||
BOOST_CHECK( 1 <= l2 );
|
||||
BOOST_CHECK( l1 <= l );
|
||||
BOOST_CHECK( l <= l2 );
|
||||
BOOST_CHECK( 2 <= l2 );
|
||||
BOOST_CHECK( l <= 2 );
|
||||
BOOST_CHECK( l2 > l1 );
|
||||
BOOST_CHECK( 2 > l1 );
|
||||
BOOST_CHECK( l2 > 1 );
|
||||
BOOST_CHECK( l2 >= l1 );
|
||||
BOOST_CHECK( 2 >= l1 );
|
||||
BOOST_CHECK( l2 >= 1 );
|
||||
BOOST_CHECK( l2 >= l );
|
||||
BOOST_CHECK( 2 >= l );
|
||||
BOOST_CHECK( l2 >= 2 );
|
||||
|
||||
cout << "Performed tests on MyShort objects.\n";
|
||||
|
||||
@@ -797,44 +798,44 @@ test_main( int , char * [] )
|
||||
MyDoubleInt di;
|
||||
MyDoubleInt tmp;
|
||||
|
||||
BOOST_TEST( di1.value() == 1 );
|
||||
BOOST_TEST( di2.value() == 2 );
|
||||
BOOST_TEST( di2.value() == 2 );
|
||||
BOOST_TEST( di.value() == 0 );
|
||||
BOOST_CHECK( di1.value() == 1 );
|
||||
BOOST_CHECK( di2.value() == 2 );
|
||||
BOOST_CHECK( di2.value() == 2 );
|
||||
BOOST_CHECK( di.value() == 0 );
|
||||
|
||||
cout << "Created MyDoubleInt objects.\n";
|
||||
|
||||
PRIVATE_EXPR_TEST( (di = di2), (di.value() == 2) );
|
||||
|
||||
BOOST_TEST( di2 == di );
|
||||
BOOST_TEST( 2 == di );
|
||||
BOOST_TEST( di == 2 );
|
||||
BOOST_TEST( di1 < di2 );
|
||||
BOOST_TEST( 1 < di2 );
|
||||
BOOST_TEST( di1 <= di2 );
|
||||
BOOST_TEST( 1 <= di2 );
|
||||
BOOST_TEST( di2 > di1 );
|
||||
BOOST_TEST( di2 > 1 );
|
||||
BOOST_TEST( di2 >= di1 );
|
||||
BOOST_TEST( di2 >= 1 );
|
||||
BOOST_TEST( di1 / di2 == half );
|
||||
BOOST_TEST( di1 / 2 == half );
|
||||
BOOST_TEST( 1 / di2 == half );
|
||||
BOOST_CHECK( di2 == di );
|
||||
BOOST_CHECK( 2 == di );
|
||||
BOOST_CHECK( di == 2 );
|
||||
BOOST_CHECK( di1 < di2 );
|
||||
BOOST_CHECK( 1 < di2 );
|
||||
BOOST_CHECK( di1 <= di2 );
|
||||
BOOST_CHECK( 1 <= di2 );
|
||||
BOOST_CHECK( di2 > di1 );
|
||||
BOOST_CHECK( di2 > 1 );
|
||||
BOOST_CHECK( di2 >= di1 );
|
||||
BOOST_CHECK( di2 >= 1 );
|
||||
BOOST_CHECK( di1 / di2 == half );
|
||||
BOOST_CHECK( di1 / 2 == half );
|
||||
BOOST_CHECK( 1 / di2 == half );
|
||||
PRIVATE_EXPR_TEST( (tmp=di1), ((tmp/=2) == half) );
|
||||
PRIVATE_EXPR_TEST( (tmp=di1), ((tmp/=di2) == half) );
|
||||
BOOST_TEST( di1 * di2 == di2 );
|
||||
BOOST_TEST( di1 * 2 == di2 );
|
||||
BOOST_TEST( 1 * di2 == di2 );
|
||||
BOOST_CHECK( di1 * di2 == di2 );
|
||||
BOOST_CHECK( di1 * 2 == di2 );
|
||||
BOOST_CHECK( 1 * di2 == di2 );
|
||||
PRIVATE_EXPR_TEST( (tmp=di1), ((tmp*=2) == di2) );
|
||||
PRIVATE_EXPR_TEST( (tmp=di1), ((tmp*=di2) == di2) );
|
||||
BOOST_TEST( di2 - di1 == di1 );
|
||||
BOOST_TEST( di2 - 1 == di1 );
|
||||
BOOST_TEST( 2 - di1 == di1 );
|
||||
BOOST_CHECK( di2 - di1 == di1 );
|
||||
BOOST_CHECK( di2 - 1 == di1 );
|
||||
BOOST_CHECK( 2 - di1 == di1 );
|
||||
PRIVATE_EXPR_TEST( (tmp=di2), ((tmp-=1) == di1) );
|
||||
PRIVATE_EXPR_TEST( (tmp=di2), ((tmp-=di1) == di1) );
|
||||
BOOST_TEST( di1 + di1 == di2 );
|
||||
BOOST_TEST( di1 + 1 == di2 );
|
||||
BOOST_TEST( 1 + di1 == di2 );
|
||||
BOOST_CHECK( di1 + di1 == di2 );
|
||||
BOOST_CHECK( di1 + 1 == di2 );
|
||||
BOOST_CHECK( 1 + di1 == di2 );
|
||||
PRIVATE_EXPR_TEST( (tmp=di1), ((tmp+=1) == di2) );
|
||||
PRIVATE_EXPR_TEST( (tmp=di1), ((tmp+=di1) == di2) );
|
||||
|
||||
@@ -845,48 +846,48 @@ test_main( int , char * [] )
|
||||
MyLongInt li;
|
||||
MyLongInt tmp2;
|
||||
|
||||
BOOST_TEST( li1.value() == 1 );
|
||||
BOOST_TEST( li2.value() == 2 );
|
||||
BOOST_TEST( li.value() == 0 );
|
||||
BOOST_CHECK( li1.value() == 1 );
|
||||
BOOST_CHECK( li2.value() == 2 );
|
||||
BOOST_CHECK( li.value() == 0 );
|
||||
|
||||
cout << "Created MyLongInt objects.\n";
|
||||
|
||||
PRIVATE_EXPR_TEST( (li = li2), (li.value() == 2) );
|
||||
|
||||
BOOST_TEST( li2 == li );
|
||||
BOOST_TEST( 2 == li );
|
||||
BOOST_TEST( li == 2 );
|
||||
BOOST_TEST( li1 < li2 );
|
||||
BOOST_TEST( 1 < li2 );
|
||||
BOOST_TEST( li1 <= li2 );
|
||||
BOOST_TEST( 1 <= li2 );
|
||||
BOOST_TEST( li2 > li1 );
|
||||
BOOST_TEST( li2 > 1 );
|
||||
BOOST_TEST( li2 >= li1 );
|
||||
BOOST_TEST( li2 >= 1 );
|
||||
BOOST_TEST( li1 % li2 == li1 );
|
||||
BOOST_TEST( li1 % 2 == li1 );
|
||||
BOOST_TEST( 1 % li2 == li1 );
|
||||
BOOST_CHECK( li2 == li );
|
||||
BOOST_CHECK( 2 == li );
|
||||
BOOST_CHECK( li == 2 );
|
||||
BOOST_CHECK( li1 < li2 );
|
||||
BOOST_CHECK( 1 < li2 );
|
||||
BOOST_CHECK( li1 <= li2 );
|
||||
BOOST_CHECK( 1 <= li2 );
|
||||
BOOST_CHECK( li2 > li1 );
|
||||
BOOST_CHECK( li2 > 1 );
|
||||
BOOST_CHECK( li2 >= li1 );
|
||||
BOOST_CHECK( li2 >= 1 );
|
||||
BOOST_CHECK( li1 % li2 == li1 );
|
||||
BOOST_CHECK( li1 % 2 == li1 );
|
||||
BOOST_CHECK( 1 % li2 == li1 );
|
||||
PRIVATE_EXPR_TEST( (tmp2=li1), ((tmp2%=2) == li1) );
|
||||
PRIVATE_EXPR_TEST( (tmp2=li1), ((tmp2%=li2) == li1) );
|
||||
BOOST_TEST( li1 / li2 == 0 );
|
||||
BOOST_TEST( li1 / 2 == 0 );
|
||||
BOOST_TEST( 1 / li2 == 0 );
|
||||
BOOST_CHECK( li1 / li2 == 0 );
|
||||
BOOST_CHECK( li1 / 2 == 0 );
|
||||
BOOST_CHECK( 1 / li2 == 0 );
|
||||
PRIVATE_EXPR_TEST( (tmp2=li1), ((tmp2/=2) == 0) );
|
||||
PRIVATE_EXPR_TEST( (tmp2=li1), ((tmp2/=li2) == 0) );
|
||||
BOOST_TEST( li1 * li2 == li2 );
|
||||
BOOST_TEST( li1 * 2 == li2 );
|
||||
BOOST_TEST( 1 * li2 == li2 );
|
||||
BOOST_CHECK( li1 * li2 == li2 );
|
||||
BOOST_CHECK( li1 * 2 == li2 );
|
||||
BOOST_CHECK( 1 * li2 == li2 );
|
||||
PRIVATE_EXPR_TEST( (tmp2=li1), ((tmp2*=2) == li2) );
|
||||
PRIVATE_EXPR_TEST( (tmp2=li1), ((tmp2*=li2) == li2) );
|
||||
BOOST_TEST( li2 - li1 == li1 );
|
||||
BOOST_TEST( li2 - 1 == li1 );
|
||||
BOOST_TEST( 2 - li1 == li1 );
|
||||
BOOST_CHECK( li2 - li1 == li1 );
|
||||
BOOST_CHECK( li2 - 1 == li1 );
|
||||
BOOST_CHECK( 2 - li1 == li1 );
|
||||
PRIVATE_EXPR_TEST( (tmp2=li2), ((tmp2-=1) == li1) );
|
||||
PRIVATE_EXPR_TEST( (tmp2=li2), ((tmp2-=li1) == li1) );
|
||||
BOOST_TEST( li1 + li1 == li2 );
|
||||
BOOST_TEST( li1 + 1 == li2 );
|
||||
BOOST_TEST( 1 + li1 == li2 );
|
||||
BOOST_CHECK( li1 + li1 == li2 );
|
||||
BOOST_CHECK( li1 + 1 == li2 );
|
||||
BOOST_CHECK( 1 + li1 == li2 );
|
||||
PRIVATE_EXPR_TEST( (tmp2=li1), ((tmp2+=1) == li2) );
|
||||
PRIVATE_EXPR_TEST( (tmp2=li1), ((tmp2+=li1) == li2) );
|
||||
|
||||
|
@@ -1,177 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>Permutation Iterator Adaptor Documentation</title>
|
||||
</head>
|
||||
|
||||
<body bgcolor="#FFFFFF" text="#000000">
|
||||
|
||||
<h1>Permutation Iterator Adaptor</h1>
|
||||
<p>Defined in header <a href="../../boost/permutation_iterator.hpp">boost/permutation_iterator.hpp</a></p>
|
||||
<p>The permutation iterator adaptor provides an iterator to a permutation of a given range.
|
||||
(<a href="http://www.cut-the-knot.com/do_you_know/permutation.html">see definition of permutation</a>).
|
||||
The adaptor takes two arguments
|
||||
<ul>
|
||||
<li>an iterator to the range V on which the <a href="http://www.cut-the-knot.com/do_you_know/permutation.html">permutation</a> will be applied</li>
|
||||
<li>the reindexing scheme that defines how the elements of V will be permuted.</li>
|
||||
</ul>
|
||||
|
||||
<p>Note that the permutation iterator is not limited to strict permutations of the given range V.
|
||||
The distance between begin and end of the reindexing iterators is allowed to be smaller compared to the
|
||||
size of the range V, in which case the permutation iterator only provides a permutation of a subrange of V.
|
||||
The indexes neither need to be unique. In this same context, it must be noted that the past the end permutation iterator is
|
||||
completely defined by means of the past-the-end iterator to the indices</p>
|
||||
|
||||
<h2>Synopsis</h2>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
namespace boost {
|
||||
template <class IndexIterator>
|
||||
class permutation_iterator_policies;
|
||||
|
||||
template <class ElementIterator, class IndexIterator>
|
||||
class permutation_iterator_generator;
|
||||
|
||||
template <class ElementIterator, class IndexIterator>
|
||||
typename permutation_iterator_generator<ElementIterator, IndexIterator>::type
|
||||
make_permutation_iterator(ElementIterator& base, IndexIterator& indexing);
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
|
||||
<h2>The Permutation Iterator Generator Class Template</h2>
|
||||
|
||||
<p>The <code>permutation_iterator_generator</code> is a helper class whose purpose
|
||||
is to construct a permutation iterator <strong>type</strong>. This class has
|
||||
two template arguments, the first being the iterator type over the range V, the
|
||||
second being the type of the iterator over the indices.
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
template <class ElementIterator, class IndexIterator>
|
||||
class permutation_iterator_generator
|
||||
{
|
||||
public:
|
||||
typedef <a href="iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a><...> type; // the resulting permutation iterator type
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
|
||||
<h3>Template Parameters</h3>
|
||||
|
||||
<table border>
|
||||
<tr>
|
||||
<th>Parameter</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td><tt>ElementIterator</tt></td>
|
||||
<td>The iterator over the elements to be permuted. This type must be a model
|
||||
of <a href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">RandomAccessIterator</a></td>
|
||||
</td>
|
||||
|
||||
<tr>
|
||||
<td><tt>IndexIterator</tt></td>
|
||||
<td>The iterator over the new indexing scheme. This type must at least be a model
|
||||
of <a href="http://www.sgi.com/tech/stl/ForwardIterator.html">ForwardIterator</a>.
|
||||
The <code>IndexIterator::value_type</code> must be convertible to the
|
||||
<code>ElementIterator::difference_type</code>.</td>
|
||||
</table>
|
||||
|
||||
<h3>Concept Model</h3>
|
||||
The permutation iterator is always a model of the same concept as the IndexIterator.
|
||||
|
||||
<h3>Members</h3>
|
||||
The permutation iterator implements the member functions
|
||||
and operators required for the
|
||||
<a href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access Iterator</a>
|
||||
concept. However, the permutation iterator can only meet the complexity guarantees
|
||||
of the same concept as the IndexIterator. Thus for instance, although the permutation
|
||||
iterator provides <code>operator+=(distance)</code>, this operation will take linear time
|
||||
in case the IndexIterator is a model of ForwardIterator instead of amortized constant time.
|
||||
|
||||
<br>
|
||||
|
||||
<h2><a name="make_generator_iterator">The Permutation Iterator Object Generator</a></h2>
|
||||
|
||||
The <code>make_permutation_iterator()</code> function provides a
|
||||
convenient way to create permutation iterator objects. The function
|
||||
saves the user the trouble of explicitly writing out the iterator
|
||||
types.
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
template <class ElementIterator, class IndexIterator >
|
||||
typename permutation_iterator_generator<ElementIterator, IndexIterator>::type
|
||||
make_permutation_iterator(ElementIterator& base, IndexIterator& indices);
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<h2>Example</h2>
|
||||
<blockquote>
|
||||
<pre>
|
||||
using namespace boost;
|
||||
int i = 0;
|
||||
|
||||
typedef std::vector< int > element_range_type;
|
||||
typedef std::list< int > index_type;
|
||||
|
||||
static const int element_range_size = 10;
|
||||
static const int index_size = 4;
|
||||
|
||||
element_range_type elements( element_range_size );
|
||||
for(element_range_type::iterator el_it = elements.begin() ; el_it != elements.end() ; ++el_it) *el_it = std::distance(elements.begin(), el_it);
|
||||
|
||||
index_type indices( index_size );
|
||||
for(index_type::iterator i_it = indices.begin() ; i_it != indices.end() ; ++i_it ) *i_it = element_range_size - index_size + std::distance(indices.begin(), i_it);
|
||||
std::reverse( indices.begin(), indices.end() );
|
||||
|
||||
typedef permutation_iterator_generator< element_range_type::iterator, index_type::iterator >::type permutation_type;
|
||||
permutation_type begin = make_permutation_iterator( elements.begin(), indices.begin() );
|
||||
permutation_type it = begin;
|
||||
permutation_type end = make_permutation_iterator( elements.begin(), indices.end() );
|
||||
|
||||
std::cout << "The original range is : ";
|
||||
std::copy( elements.begin(), elements.end(), std::ostream_iterator< int >( std::cout, " " ) );
|
||||
std::cout << "\n";
|
||||
|
||||
std::cout << "The reindexing scheme is : ";
|
||||
std::copy( indices.begin(), indices.end(), std::ostream_iterator< int >( std::cout, " " ) );
|
||||
std::cout << "\n";
|
||||
|
||||
std::cout << "The permutated range is : ";
|
||||
std::copy( begin, end, std::ostream_iterator< int >( std::cout, " " ) );
|
||||
std::cout << "\n";
|
||||
|
||||
std::cout << "Elements at even indices in the permutation : ";
|
||||
it = begin;
|
||||
for(i = 0; i < index_size / 2 ; ++i, it+=2 ) std::cout << *it << " ";
|
||||
std::cout << "\n";
|
||||
|
||||
std::cout << "Permutation backwards : ";
|
||||
it = begin + (index_size);
|
||||
assert( it != begin );
|
||||
for( ; it-- != begin ; ) std::cout << *it << " ";
|
||||
std::cout << "\n";
|
||||
|
||||
std::cout << "Iterate backward with stride 2 : ";
|
||||
it = begin + (index_size - 1);
|
||||
for(i = 0 ; i < index_size / 2 ; ++i, it-=2 ) std::cout << *it << " ";
|
||||
std::cout << "\n";
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<br><br><br><hr>
|
||||
Thanks: The permutation iterator is only a small addition to the superb iterator adaptors
|
||||
library of David Abrahams and Jeremy Siek.
|
||||
<br><br>
|
||||
|
||||
Copyright 2001 Toon Knapen.
|
||||
|
||||
</body>
|
||||
</html>
|
@@ -1,391 +0,0 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
||||
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
|
||||
<meta name="ProgId" content="FrontPage.Editor.Document">
|
||||
<title>Projection Iterator Adaptor Documentation</title>
|
||||
</head>
|
||||
|
||||
<body bgcolor="#FFFFFF" text="#000000">
|
||||
|
||||
<img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)"
|
||||
align="center" width="277" height="86">
|
||||
|
||||
<h1>Projection Iterator Adaptor</h1>
|
||||
|
||||
Defined in header
|
||||
<a href="../../boost/iterator_adaptors.hpp">boost/iterator_adaptors.hpp</a>
|
||||
|
||||
<p>
|
||||
The projection iterator adaptor is similar to the <a
|
||||
href="./transform_iterator.htm">transform iterator adaptor</a> in that
|
||||
its <tt>operator*()</tt> applies some function to the result of
|
||||
dereferencing the base iterator and then returns the result. The
|
||||
difference is that the function must return a reference to some
|
||||
existing object (for example, a data member within the
|
||||
<tt>value_type</tt> of the base iterator). The following
|
||||
<b>pseudo-code</b> gives the basic idea. The data member <tt>p</tt> is
|
||||
the function object.
|
||||
|
||||
<pre>
|
||||
reference projection_iterator::operator*() const {
|
||||
return this->p(*this->base_iterator);
|
||||
}
|
||||
</pre>
|
||||
|
||||
<h2>Synopsis</h2>
|
||||
|
||||
<pre>
|
||||
namespace boost {
|
||||
template <class <a href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html">AdaptableUnaryFunction</a>, class BaseIterator>
|
||||
struct projection_iterator_generator;
|
||||
|
||||
template <class <a href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html">AdaptableUnaryFunction</a>,
|
||||
class BaseIterator, class ConstBaseIterator>
|
||||
struct projection_iterator_pair_generator;
|
||||
|
||||
template <class <a href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html">AdaptableUnaryFunction</a>, class BaseIterator>
|
||||
typename projection_iterator_generator<AdaptableUnaryFunction, BaseIterator>::type
|
||||
make_projection_iterator(BaseIterator base,
|
||||
const AdaptableUnaryFunction& p = AdaptableUnaryFunction())
|
||||
|
||||
template <class <a href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html">AdaptableUnaryFunction</a>, class ConstBaseIterator>
|
||||
typename projection_iterator_generator<AdaptableUnaryFunction, ConstBaseIterator>::type
|
||||
make_const_projection_iterator(ConstBaseIterator base,
|
||||
const AdaptableUnaryFunction& p = AdaptableUnaryFunction())
|
||||
}
|
||||
</pre>
|
||||
|
||||
<hr>
|
||||
|
||||
<h2><a name="projection_iterator_generator">The Projection Iterator Type
|
||||
Generator</a></h2>
|
||||
|
||||
The class <tt>projection_iterator_generator</tt> is a helper class
|
||||
whose purpose is to construct an projection iterator type. The main
|
||||
template parameter for this class is the <a
|
||||
href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html"><tt>AdaptableUnaryFunction</tt></a>
|
||||
function object type and the <tt>BaseIterator</tt> type that is being
|
||||
wrapped.
|
||||
|
||||
<pre>
|
||||
template <class <a href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html">AdaptableUnaryFunction</a>, class BaseIterator>
|
||||
class projection_iterator_generator
|
||||
{
|
||||
public:
|
||||
typedef <tt><a href="./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a><...></tt> type; // the resulting projection iterator type
|
||||
};
|
||||
</pre>
|
||||
|
||||
<h3>Example</h3>
|
||||
|
||||
In the following example we have a list of personnel records. Each
|
||||
record has an employee's name and ID number. We want to be able to
|
||||
traverse through the list accessing either the name or the ID numbers
|
||||
of the employees using the projection iterator so we create the
|
||||
function object classes <tt>select_name</tt> and
|
||||
<tt>select_ID</tt>. We then use the
|
||||
<tt>projection_iterator_generator</tt> class to create a projection
|
||||
iterator and use it to print out the names of the employees.
|
||||
|
||||
<pre>
|
||||
#include <boost/config.hpp>
|
||||
#include <list>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <boost/iterator_adaptors.hpp>
|
||||
|
||||
struct personnel_record {
|
||||
personnel_record(std::string n, int id) : m_name(n), m_ID(id) { }
|
||||
std::string m_name;
|
||||
int m_ID;
|
||||
};
|
||||
|
||||
struct select_name {
|
||||
typedef personnel_record argument_type;
|
||||
typedef std::string result_type;
|
||||
const std::string& operator()(const personnel_record& r) const {
|
||||
return r.m_name;
|
||||
}
|
||||
std::string& operator()(personnel_record& r) const {
|
||||
return r.m_name;
|
||||
}
|
||||
};
|
||||
|
||||
struct select_ID {
|
||||
typedef personnel_record argument_type;
|
||||
typedef int result_type;
|
||||
const int& operator()(const personnel_record& r) const {
|
||||
return r.m_ID;
|
||||
}
|
||||
int& operator()(personnel_record& r) const {
|
||||
return r.m_ID;
|
||||
}
|
||||
};
|
||||
|
||||
int main(int, char*[])
|
||||
{
|
||||
std::list<personnel_record> personnel_list;
|
||||
|
||||
personnel_list.push_back(personnel_record("Barney", 13423));
|
||||
personnel_list.push_back(personnel_record("Fred", 12343));
|
||||
personnel_list.push_back(personnel_record("Wilma", 62454));
|
||||
personnel_list.push_back(personnel_record("Betty", 20490));
|
||||
|
||||
// Example of using projection_iterator_generator
|
||||
// to print out the names in the personnel list.
|
||||
|
||||
boost::projection_iterator_generator<select_name,
|
||||
std::list<personnel_record>::iterator>::type
|
||||
personnel_first(personnel_list.begin()),
|
||||
personnel_last(personnel_list.end());
|
||||
|
||||
std::copy(personnel_first, personnel_last,
|
||||
std::ostream_iterator<std::string>(std::cout, "\n"));
|
||||
std::cout << std::endl;
|
||||
|
||||
// to be continued...
|
||||
</pre>
|
||||
The output for this part is:
|
||||
<pre>
|
||||
Barney
|
||||
Fred
|
||||
Wilma
|
||||
Betty
|
||||
</pre>
|
||||
|
||||
<h3>Template Parameters</h3>
|
||||
|
||||
<Table border>
|
||||
<TR>
|
||||
<TH>Parameter</TH><TH>Description</TH>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><a href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html"><tt>AdaptableUnaryFunction</tt></a></TD>
|
||||
<TD>The type of the function object. The <tt>argument_type</tt> of the
|
||||
function must match the value type of the base iterator. The function
|
||||
should return a reference to the function's <tt>result_type</tt>.
|
||||
The <tt>result_type</tt> will be the resulting iterator's <tt>value_type</tt>.
|
||||
</TD>
|
||||
</TD>
|
||||
|
||||
<TR>
|
||||
<TD><tt>BaseIterator</tt></TD>
|
||||
<TD>The iterator type being wrapped.</TD>
|
||||
</TD>
|
||||
</TR>
|
||||
|
||||
</Table>
|
||||
|
||||
<h3>Model of</h3>
|
||||
|
||||
If the base iterator is a model of <a
|
||||
href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random
|
||||
Access Iterator</a> then so is the resulting projection iterator. If
|
||||
the base iterator supports less functionality than this the resulting
|
||||
projection iterator will also support less functionality.
|
||||
|
||||
<h3>Members</h3>
|
||||
|
||||
The projection iterator type implements the member functions and
|
||||
operators required of the <a
|
||||
href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random
|
||||
Access Iterator</a> concept.
|
||||
In addition it has the following constructor:
|
||||
|
||||
<pre>
|
||||
projection_iterator_generator::type(const BaseIterator& it,
|
||||
const AdaptableUnaryFunction& p = AdaptableUnaryFunction())
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
<hr>
|
||||
<p>
|
||||
|
||||
<h2><a name="projection_iterator_pair_generator">The Projection Iterator Pair
|
||||
Generator</a></h2>
|
||||
|
||||
Sometimes a mutable/const pair of iterator types is needed, such as
|
||||
when implementing a container type. The
|
||||
<tt>projection_iterator_pair_generator</tt> class makes it more
|
||||
convenient to create this pair of iterator types.
|
||||
|
||||
<pre>
|
||||
template <class <a href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html">AdaptableUnaryFunction</a>, class BaseIterator, class ConstBaseIterator>
|
||||
class projection_iterator_pair_generator
|
||||
{
|
||||
public:
|
||||
typedef <tt><a href="./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a><...></tt> iterator; // the mutable projection iterator type
|
||||
typedef <tt><a href="./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a><...></tt> const_iterator; // the immutable projection iterator type
|
||||
};
|
||||
</pre>
|
||||
|
||||
<h3>Example</h3>
|
||||
|
||||
In this part of the example we use the
|
||||
<tt>projection_iterator_pair_generator</tt> to create a mutable/const
|
||||
pair of projection iterators that access the ID numbers of the
|
||||
personnel. We use the mutable iterator to re-index the ID numbers from
|
||||
zero. We then use the constant iterator to print the ID numbers out.
|
||||
|
||||
<pre>
|
||||
// continuing from the last example...
|
||||
|
||||
typedef boost::projection_iterator_pair_generator<select_ID,
|
||||
std::list<personnel_record>::iterator,
|
||||
std::list<personnel_record>::const_iterator> PairGen;
|
||||
|
||||
PairGen::iterator ID_first(personnel_list.begin()),
|
||||
ID_last(personnel_list.end());
|
||||
|
||||
int new_id = 0;
|
||||
while (ID_first != ID_last) {
|
||||
*ID_first = new_id++;
|
||||
++ID_first;
|
||||
}
|
||||
|
||||
PairGen::const_iterator const_ID_first(personnel_list.begin()),
|
||||
const_ID_last(personnel_list.end());
|
||||
|
||||
std::copy(const_ID_first, const_ID_last,
|
||||
std::ostream_iterator<int>(std::cout, " "));
|
||||
std::cout << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
// to be continued...
|
||||
</pre>
|
||||
The output is:
|
||||
<pre>
|
||||
0 1 2 3
|
||||
</pre>
|
||||
|
||||
<h3>Template Parameters</h3>
|
||||
|
||||
<Table border>
|
||||
<TR>
|
||||
<TH>Parameter</TH><TH>Description</TH>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><a href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html"><tt>AdaptableUnaryFunction</tt></a></TD>
|
||||
<TD>The type of the function object. The <tt>argument_type</tt> of the
|
||||
function must match the value type of the base iterator. The function
|
||||
should return a true reference to the function's <tt>result_type</tt>.
|
||||
The <tt>result_type</tt> will be the resulting iterator's <tt>value_type</tt>.
|
||||
</TD>
|
||||
</TD>
|
||||
|
||||
<TR>
|
||||
<TD><tt>BaseIterator</tt></TD>
|
||||
<TD>The mutable iterator type being wrapped.</TD>
|
||||
</TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><tt>ConstBaseIterator</tt></TD>
|
||||
<TD>The constant iterator type being wrapped.</TD>
|
||||
</TD>
|
||||
</TR>
|
||||
|
||||
</Table>
|
||||
|
||||
<h3>Model of</h3>
|
||||
|
||||
If the base iterator types model the <a
|
||||
href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random
|
||||
Access Iterator</a> then so do the resulting projection iterator
|
||||
types. If the base iterators support less functionality the
|
||||
resulting projection iterator types will also support less
|
||||
functionality. The resulting <tt>iterator</tt> type is mutable, and
|
||||
the resulting <tt>const_iterator</tt> type is constant.
|
||||
|
||||
<h3>Members</h3>
|
||||
|
||||
The resulting <tt>iterator</tt> and <tt>const_iterator</tt> types
|
||||
implements the member functions and operators required of the <a
|
||||
href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random
|
||||
Access Iterator</a> concept. In addition they support the following
|
||||
constructors:
|
||||
|
||||
<pre>
|
||||
projection_iterator_pair_generator::iterator(const BaseIterator& it,
|
||||
const AdaptableUnaryFunction& p = AdaptableUnaryFunction())</pre>
|
||||
|
||||
<pre>
|
||||
projection_iterator_pair_generator::const_iterator(const BaseIterator& it,
|
||||
const AdaptableUnaryFunction& p = AdaptableUnaryFunction())
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
<hr>
|
||||
<p>
|
||||
|
||||
<h2><a name="make_projection_iterator">The Projection Iterator Object Generators</a></h2>
|
||||
|
||||
The <tt>make_projection_iterator()</tt> and
|
||||
<tt>make_const_projection_iterator()</tt> functions provide a more
|
||||
convenient way to create projection iterator objects. The functions
|
||||
save the user the trouble of explicitly writing out the iterator
|
||||
types.
|
||||
|
||||
<pre>
|
||||
template <class <a href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html">AdaptableUnaryFunction</a>, class BaseIterator>
|
||||
typename projection_iterator_generator<AdaptableUnaryFunction, BaseIterator>::type
|
||||
make_projection_iterator(BaseIterator base,
|
||||
const AdaptableUnaryFunction& p = AdaptableUnaryFunction())
|
||||
|
||||
template <class <a href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html">AdaptableUnaryFunction</a>, class ConstBaseIterator>
|
||||
typename projection_iterator_generator<AdaptableUnaryFunction, ConstBaseIterator>::type
|
||||
make_const_projection_iterator(ConstBaseIterator base,
|
||||
const AdaptableUnaryFunction& p = AdaptableUnaryFunction())
|
||||
</pre>
|
||||
|
||||
|
||||
<h3>Example</h3>
|
||||
|
||||
In this part of the example, we again print out the names of the
|
||||
personnel, but this time we use the
|
||||
<tt>make_const_projection_iterator()</tt> function to save some typing.
|
||||
|
||||
<pre>
|
||||
// continuing from the last example...
|
||||
|
||||
std::copy
|
||||
(boost::make_const_projection_iterator<select_name>(personnel_list.begin()),
|
||||
boost::make_const_projection_iterator<select_name>(personnel_list.end()),
|
||||
std::ostream_iterator<std::string>(std::cout, "\n"));
|
||||
|
||||
return 0;
|
||||
}
|
||||
</pre>
|
||||
The output is:
|
||||
<pre>
|
||||
Barney
|
||||
Fred
|
||||
Wilma
|
||||
Betty
|
||||
</pre>
|
||||
|
||||
<hr>
|
||||
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->19 Aug 2001<!--webbot bot="Timestamp" endspan i-checksum="14767" --></p>
|
||||
<p><EFBFBD> Copyright Jeremy Siek 2000. Permission to copy, use,
|
||||
modify, sell and distribute this document is granted provided this copyright
|
||||
notice appears in all copies. This document is provided "as is"
|
||||
without express or implied warranty, and with no claim as to its suitability for
|
||||
any purpose.</p>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
<!-- LocalWords: html charset alt gif hpp BaseIterator const namespace struct
|
||||
-->
|
||||
<!-- LocalWords: ConstPointer ConstReference typename iostream int abcdefg
|
||||
-->
|
||||
<!-- LocalWords: sizeof PairGen pre Siek htm AdaptableUnaryFunction
|
||||
-->
|
||||
<!-- LocalWords: ConstBaseIterator
|
||||
-->
|
@@ -1,103 +0,0 @@
|
||||
// (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <list>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <boost/iterator/transform_iterator.hpp>
|
||||
|
||||
struct personnel_record {
|
||||
personnel_record(std::string n, int id) : m_name(n), m_ID(id) { }
|
||||
std::string m_name;
|
||||
int m_ID;
|
||||
};
|
||||
|
||||
struct select_name {
|
||||
typedef personnel_record argument_type;
|
||||
typedef std::string const& result_type;
|
||||
const std::string& operator()(const personnel_record& r) const {
|
||||
return r.m_name;
|
||||
}
|
||||
std::string& operator()(personnel_record& r) const {
|
||||
return r.m_name;
|
||||
}
|
||||
};
|
||||
|
||||
struct select_ID {
|
||||
typedef personnel_record argument_type;
|
||||
typedef int& result_type;
|
||||
const int& operator()(const personnel_record& r) const {
|
||||
return r.m_ID;
|
||||
}
|
||||
int& operator()(personnel_record& r) const {
|
||||
return r.m_ID;
|
||||
}
|
||||
};
|
||||
|
||||
int main(int, char*[])
|
||||
{
|
||||
std::list<personnel_record> personnel_list;
|
||||
|
||||
personnel_list.push_back(personnel_record("Barney", 13423));
|
||||
personnel_list.push_back(personnel_record("Fred", 12343));
|
||||
personnel_list.push_back(personnel_record("Wilma", 62454));
|
||||
personnel_list.push_back(personnel_record("Betty", 20490));
|
||||
|
||||
// Example of using transform_iterator to print out the names in the
|
||||
// personnel list using a projection.
|
||||
|
||||
boost::transform_iterator<
|
||||
select_name
|
||||
, std::list<personnel_record>::iterator
|
||||
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
, std::string
|
||||
#endif
|
||||
>
|
||||
personnel_first(personnel_list.begin()),
|
||||
personnel_last(personnel_list.end());
|
||||
|
||||
std::copy(personnel_first, personnel_last,
|
||||
std::ostream_iterator<std::string>(std::cout, "\n"));
|
||||
std::cout << std::endl;
|
||||
|
||||
// Example of using transform_iterator with const_iterators to
|
||||
// assign new ID numbers to the personnel.
|
||||
|
||||
boost::transform_iterator<
|
||||
select_ID, std::list<personnel_record>::iterator
|
||||
> ID_first(personnel_list.begin()),
|
||||
ID_last(personnel_list.end());
|
||||
|
||||
int new_id = 0;
|
||||
while (ID_first != ID_last) {
|
||||
*ID_first = new_id++;
|
||||
++ID_first;
|
||||
}
|
||||
|
||||
boost::transform_iterator<
|
||||
select_ID, std::list<personnel_record>::const_iterator, int const&
|
||||
>
|
||||
const_ID_first(personnel_list.begin()),
|
||||
const_ID_last(personnel_list.end());
|
||||
|
||||
std::copy(const_ID_first, const_ID_last,
|
||||
std::ostream_iterator<int>(std::cout, " "));
|
||||
std::cout << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
// Example of using make_const_projection_iterator()
|
||||
// to print out the names in the personnel list again.
|
||||
std::copy(
|
||||
boost::make_transform_iterator<select_name>(personnel_list.begin())
|
||||
, boost::make_transform_iterator<select_name>(personnel_list.end())
|
||||
, std::ostream_iterator<std::string>(std::cout, "\n"));
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
@@ -1,9 +1,18 @@
|
||||
// Copyright David Abrahams and Aleksey Gurtovoy
|
||||
// 2002-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)
|
||||
|
||||
// compile-time test for "boost/ref.hpp" header content
|
||||
// see 'ref_test.cpp' for run-time part
|
||||
|
||||
#include <boost/ref.hpp>
|
||||
#include <boost/type_traits/same_traits.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
#include <boost/mpl/assert.hpp>
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -30,13 +39,23 @@ void is_reference_wrapper_test(T)
|
||||
template< typename R, typename Ref >
|
||||
void cxx_reference_test(Ref)
|
||||
{
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, < 0x600)
|
||||
typedef typename boost::remove_const<Ref>::type ref;
|
||||
BOOST_STATIC_ASSERT((boost::is_same<R,ref>::value));
|
||||
#else
|
||||
BOOST_STATIC_ASSERT((boost::is_same<R,Ref>::value));
|
||||
#endif
|
||||
}
|
||||
|
||||
template< typename R, typename Ref >
|
||||
void unwrap_reference_test(Ref)
|
||||
{
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, < 0x600)
|
||||
typedef typename boost::remove_const<Ref>::type ref;
|
||||
typedef typename boost::unwrap_reference<ref>::type type;
|
||||
#else
|
||||
typedef typename boost::unwrap_reference<Ref>::type type;
|
||||
#endif
|
||||
BOOST_STATIC_ASSERT((boost::is_same<R,type>::value));
|
||||
}
|
||||
|
||||
|
12
ref_test.cpp
12
ref_test.cpp
@@ -1,3 +1,7 @@
|
||||
// Copyright David Abrahams and Aleksey Gurtovoy
|
||||
// 2002-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)
|
||||
|
||||
// run-time test for "boost/ref.hpp" header content
|
||||
// see 'ref_ct_test.cpp' for compile-time part
|
||||
@@ -56,11 +60,11 @@ struct ref_wrapper
|
||||
|
||||
static void test(T x)
|
||||
{
|
||||
BOOST_TEST(passthru(ref(x)) == &x);
|
||||
BOOST_TEST(&ref(x).get() == &x);
|
||||
BOOST_CHECK(passthru(ref(x)) == &x);
|
||||
BOOST_CHECK(&ref(x).get() == &x);
|
||||
|
||||
BOOST_TEST(cref_passthru(cref(x)) == &x);
|
||||
BOOST_TEST(&cref(x).get() == &x);
|
||||
BOOST_CHECK(cref_passthru(cref(x)) == &x);
|
||||
BOOST_CHECK(&cref(x).get() == &x);
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -1,331 +0,0 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<meta name="generator" content="HTML Tidy, see www.w3.org">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
||||
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
|
||||
<meta name="ProgId" content="FrontPage.Editor.Document">
|
||||
|
||||
<title>Reverse Iterator Adaptor Documentation</title>
|
||||
</head>
|
||||
|
||||
<body bgcolor="#FFFFFF" text="#000000">
|
||||
<img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align=
|
||||
"center" width="277" height="86">
|
||||
|
||||
<h1>Reverse Iterator Adaptor</h1>
|
||||
Defined in header <a href=
|
||||
"../../boost/iterator_adaptors.hpp">boost/iterator_adaptors.hpp</a>
|
||||
|
||||
<p>The reverse iterator adaptor flips the direction of a base iterator's
|
||||
motion. Invoking <tt>operator++()</tt> moves the base iterator backward and
|
||||
invoking <tt>operator--()</tt> moves the base iterator forward. The Boost
|
||||
reverse iterator adaptor is better to use than the
|
||||
<tt>std::reverse_iterator</tt> class in situations where pairs of
|
||||
mutable/constant iterators are needed (e.g., in containers) because
|
||||
comparisons and conversions between the mutable and const versions are
|
||||
implemented correctly.
|
||||
|
||||
<h2>Synopsis</h2>
|
||||
<pre>
|
||||
namespace boost {
|
||||
template <class <a href=
|
||||
"http://www.sgi.com/tech/stl/BidirectionalIterator.html">BidirectionalIterator</a>,
|
||||
class Value, class Reference, class Pointer, class Category, class Distance>
|
||||
struct reverse_iterator_generator;
|
||||
|
||||
template <class <a href=
|
||||
"http://www.sgi.com/tech/stl/BidirectionalIterator.html">BidirectionalIterator</a>>
|
||||
typename reverse_iterator_generator<BidirectionalIterator>::type
|
||||
make_reverse_iterator(BidirectionalIterator base)
|
||||
}
|
||||
</pre>
|
||||
<hr>
|
||||
|
||||
<h2><a name="reverse_iterator_generator">The Reverse Iterator Type
|
||||
Generator</a></h2>
|
||||
The <tt>reverse_iterator_generator</tt> template is a <a href=
|
||||
"../../more/generic_programming.html#type_generator">generator</a> of
|
||||
reverse iterator types. The main template parameter for this class is the
|
||||
base <tt>BidirectionalIterator</tt> type that is being adapted. In most
|
||||
cases the associated types of the base iterator can be deduced using
|
||||
<tt>std::iterator_traits</tt>, but in some situations the user may want to
|
||||
override these types, so there are also template parameters for the base
|
||||
iterator's associated types.
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
template <class <a href=
|
||||
"http://www.sgi.com/tech/stl/BidirectionalIterator.html">BidirectionalIterator</a>,
|
||||
class Value, class Reference, class Pointer, class Category, class Distance>
|
||||
class reverse_iterator_generator
|
||||
{
|
||||
public:
|
||||
typedef <tt><a href=
|
||||
"./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a><...></tt> type; // the resulting reverse iterator type
|
||||
};
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<h3>Example</h3>
|
||||
In this example we sort a sequence of letters and then output the sequence
|
||||
in descending order using reverse iterators.
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
#include <boost/config.hpp>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <boost/iterator_adaptors.hpp>
|
||||
|
||||
int main(int, char*[])
|
||||
{
|
||||
char letters[] = "hello world!";
|
||||
const int N = sizeof(letters)/sizeof(char) - 1;
|
||||
std::cout << "original sequence of letters:\t"
|
||||
<< letters << std::endl;
|
||||
|
||||
std::sort(letters, letters + N);
|
||||
|
||||
// Use reverse_iterator_generator to print a sequence
|
||||
// of letters in reverse order.
|
||||
|
||||
boost::reverse_iterator_generator<char*>::type
|
||||
reverse_letters_first(letters + N),
|
||||
reverse_letters_last(letters);
|
||||
|
||||
std::cout << "letters in descending order:\t";
|
||||
std::copy(reverse_letters_first, reverse_letters_last,
|
||||
std::ostream_iterator<char>(std::cout));
|
||||
std::cout << std::endl;
|
||||
|
||||
// to be continued...
|
||||
</pre>
|
||||
</blockquote>
|
||||
The output is:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
original sequence of letters: hello world!
|
||||
letters in descending order: wroolllhed!
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<h3>Template Parameters</h3>
|
||||
|
||||
<table border>
|
||||
<tr>
|
||||
<th>Parameter
|
||||
|
||||
<th>Description
|
||||
|
||||
<tr>
|
||||
<td><tt><a href=
|
||||
"http://www.sgi.com/tech/stl/BidirectionalIterator.html">BidirectionalIterator</a></tt>
|
||||
|
||||
|
||||
<td>The iterator type being wrapped.
|
||||
|
||||
<tr>
|
||||
<td><tt>Value</tt>
|
||||
|
||||
<td>The value-type of the base iterator and the resulting reverse
|
||||
iterator.<br>
|
||||
<b>Default:</b><tt>std::iterator_traits<BidirectionalIterator>::value_type</tt>
|
||||
|
||||
|
||||
<tr>
|
||||
<td><tt>Reference</tt>
|
||||
|
||||
<td>The <tt>reference</tt> type of the resulting iterator, and in
|
||||
particular, the result type of <tt>operator*()</tt>.<br>
|
||||
<b>Default:</b> If <tt>Value</tt> is supplied, <tt>Value&</tt> is
|
||||
used. Otherwise
|
||||
<tt>std::iterator_traits<BidirectionalIterator>::reference</tt>
|
||||
is used.
|
||||
|
||||
<tr>
|
||||
<td><tt>Pointer</tt>
|
||||
|
||||
<td>The <tt>pointer</tt> type of the resulting iterator, and in
|
||||
particular, the result type of <tt>operator->()</tt>.<br>
|
||||
<b>Default:</b> If <tt>Value</tt> was supplied, then <tt>Value*</tt>,
|
||||
otherwise
|
||||
<tt>std::iterator_traits<BidirectionalIterator>::pointer</tt>.
|
||||
|
||||
<tr>
|
||||
<td><tt>Category</tt>
|
||||
|
||||
<td>The <tt>iterator_category</tt> type for the resulting iterator.<br>
|
||||
<b>Default:</b>
|
||||
<tt>std::iterator_traits<BidirectionalIterator>::iterator_category</tt>
|
||||
|
||||
|
||||
<tr>
|
||||
<td><tt>Distance</tt>
|
||||
|
||||
<td>The <tt>difference_type</tt> for the resulting iterator.<br>
|
||||
<b>Default:</b>
|
||||
<tt>std::iterator_traits<BidirectionalIterator&gt::difference_type</tt>
|
||||
|
||||
</table>
|
||||
|
||||
<h3>Concept Model</h3>
|
||||
The indirect iterator will model whichever <a href=
|
||||
"http://www.sgi.com/tech/stl/Iterators.html">standard iterator concept
|
||||
category</a> is modeled by the base iterator. Thus, if the base iterator is
|
||||
a model of <a href=
|
||||
"http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access
|
||||
Iterator</a> then so is the resulting indirect iterator. If the base
|
||||
iterator models a more restrictive concept, the resulting indirect iterator
|
||||
will model the same concept. The base iterator must be at least a <a href=
|
||||
"http://www.sgi.com/tech/stl/BidirectionalIterator.html">Bidirectional
|
||||
Iterator</a>
|
||||
|
||||
<h3>Members</h3>
|
||||
The reverse iterator type implements the member functions and operators
|
||||
required of the <a href=
|
||||
"http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access
|
||||
Iterator</a> concept. In addition it has the following constructor:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
reverse_iterator_generator::type(const BidirectionalIterator& it)
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
|
||||
<br>
|
||||
<br>
|
||||
|
||||
<hr>
|
||||
|
||||
<p>
|
||||
|
||||
<h2><a name="make_reverse_iterator">The Reverse Iterator Object
|
||||
Generator</a></h2>
|
||||
The <tt>make_reverse_iterator()</tt> function provides a more convenient
|
||||
way to create reverse iterator objects. The function saves the user the
|
||||
trouble of explicitly writing out the iterator types.
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
template <class BidirectionalIterator>
|
||||
typename reverse_iterator_generator<BidirectionalIterator>::type
|
||||
make_reverse_iterator(BidirectionalIterator base);
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<h3>Example</h3>
|
||||
In this part of the example we use <tt>make_reverse_iterator()</tt> to
|
||||
print the sequence of letters in reverse-reverse order, which is the
|
||||
original order.
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
// continuing from the previous example...
|
||||
|
||||
std::cout << "letters in ascending order:\t";
|
||||
std::copy(boost::make_reverse_iterator(reverse_letters_last),
|
||||
boost::make_reverse_iterator(reverse_letters_first),
|
||||
std::ostream_iterator<char>(std::cout));
|
||||
std::cout << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
The output is:
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
letters in ascending order: !dehllloorw
|
||||
</pre>
|
||||
</blockquote>
|
||||
<hr>
|
||||
|
||||
<h2><a name="interactions">Constant/Mutable Iterator Interactions</a></h2>
|
||||
|
||||
<p>One failing of the standard <tt><a
|
||||
href="http://www.sgi.com/tech/stl/ReverseIterator.html">reverse_iterator</a></tt>
|
||||
adaptor is that it doesn't properly support interactions between adapted
|
||||
<tt>const</tt> and non-<tt>const</tt> iterators. For example:
|
||||
<blockquote>
|
||||
<pre>
|
||||
#include <vector>
|
||||
|
||||
template <class T> void convert(T x) {}
|
||||
|
||||
// Test interactions of a matched pair of random access iterators
|
||||
template <class Iterator, class ConstIterator>
|
||||
void test_interactions(Iterator i, ConstIterator ci)
|
||||
{
|
||||
bool eq = i == ci; // comparisons
|
||||
bool ne = i != ci;
|
||||
bool lt = i < ci;
|
||||
bool le = i <= ci;
|
||||
bool gt = i > ci;
|
||||
bool ge = i >= ci;
|
||||
std::size_t distance = i - ci; // difference
|
||||
ci = i; // assignment
|
||||
ConstIterator ci2(i); // construction
|
||||
convert<ConstIterator>(i); // implicit conversion
|
||||
}
|
||||
|
||||
void f()
|
||||
{
|
||||
typedef std::vector<int> vec;
|
||||
vec v;
|
||||
const vec& cv;
|
||||
|
||||
test_interactions(v.begin(), cv.begin()); // <font color="#007F00">OK</font>
|
||||
test_interactions(v.rbegin(), cv.rbegin()); // <font color="#FF0000">ERRORS ON EVERY TEST!!</font>
|
||||
</pre>
|
||||
</blockquote>
|
||||
Reverse iterators created with <tt>boost::reverse_iterator_generator</tt> don't have this problem, though:
|
||||
<blockquote>
|
||||
<pre>
|
||||
typedef boost::reverse_iterator_generator<vec::iterator>::type ri;
|
||||
typedef boost::reverse_iterator_generator<vec::const_iterator>::type cri;
|
||||
test_interactions(ri(v.begin()), cri(cv.begin())); // <font color="#007F00">OK!!</font>
|
||||
</pre>
|
||||
</blockquote>
|
||||
Or, more simply,
|
||||
<blockquote>
|
||||
<pre>
|
||||
test_interactions(
|
||||
boost::make_reverse_iterator(v.begin()),
|
||||
boost::make_reverse_iterator(cv.begin())); // <font color="#007F00">OK!!</font>
|
||||
}
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>If you are wondering why there is no
|
||||
<tt>reverse_iterator_pair_generator</tt> in the manner of <tt><a
|
||||
href="projection_iterator.htm#projection_iterator_pair_generator">projection_iterator_pair_generator</a></tt>,
|
||||
the answer is simple: we tried it, but found that in practice it took
|
||||
<i>more</i> typing to use <tt>reverse_iterator_pair_generator</tt> than to
|
||||
simply use <tt>reverse_iterator_generator</tt> twice!<br><br>
|
||||
|
||||
<hr>
|
||||
|
||||
|
||||
<p>Revised
|
||||
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->19 Aug 2001<!--webbot bot="Timestamp" endspan i-checksum="14767" -->
|
||||
|
||||
|
||||
<p>© Copyright Jeremy Siek 2000. Permission to copy, use, modify, sell
|
||||
and distribute this document is granted provided this copyright notice
|
||||
appears in all copies. This document is provided "as is" without express or
|
||||
implied warranty, and with no claim as to its suitability for any purpose.
|
||||
<!-- LocalWords: html charset alt gif hpp BidirectionalIterator const namespace struct
|
||||
-->
|
||||
|
||||
<!-- LocalWords: ConstPointer ConstReference typename iostream int abcdefg
|
||||
-->
|
||||
<!-- LocalWords: sizeof PairGen pre Siek wroolllhed dehllloorw
|
||||
-->
|
||||
</body>
|
||||
</html>
|
||||
|
@@ -1,47 +0,0 @@
|
||||
// (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <boost/iterator/reverse_iterator.hpp>
|
||||
#include <boost/detail/iterator.hpp>
|
||||
|
||||
//boost::detail::iterator_traits
|
||||
int main(int, char*[])
|
||||
{
|
||||
char letters_[] = "hello world!";
|
||||
const int N = sizeof(letters_)/sizeof(char) - 1;
|
||||
typedef char* base_iterator;
|
||||
base_iterator letters(letters_);
|
||||
|
||||
std::cout << "original sequence of letters:\t"
|
||||
<< letters_ << std::endl;
|
||||
|
||||
std::sort(letters, letters + N);
|
||||
|
||||
// Use reverse_iterator_generator to print a sequence
|
||||
// of letters in reverse order.
|
||||
|
||||
boost::reverse_iterator<base_iterator>
|
||||
reverse_letters_first(letters + N),
|
||||
reverse_letters_last(letters);
|
||||
|
||||
std::cout << "letters in descending order:\t";
|
||||
std::copy(reverse_letters_first, reverse_letters_last,
|
||||
std::ostream_iterator<char>(std::cout));
|
||||
std::cout << std::endl;
|
||||
|
||||
// Use make_reverse_iterator() to print the sequence
|
||||
// of letters in reverse-reverse order.
|
||||
|
||||
std::cout << "letters in ascending order:\t";
|
||||
std::copy(boost::make_reverse_iterator(reverse_letters_last),
|
||||
boost::make_reverse_iterator(reverse_letters_first),
|
||||
std::ostream_iterator<char>(std::cout));
|
||||
std::cout << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
@@ -9,7 +9,7 @@
|
||||
|
||||
<body bgcolor="#FFFFFF" text="#000000">
|
||||
|
||||
<img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)"
|
||||
<img src="../../boost.png" alt="boost.png (6897 bytes)"
|
||||
align="center" width="277" height="86">
|
||||
|
||||
<h1>Shared Container Iterator</h1>
|
||||
@@ -312,11 +312,10 @@ the previous two.
|
||||
<!-- hhmts start -->
|
||||
Last modified: Mon Aug 11 11:27:03 EST 2003
|
||||
<!-- hhmts end -->
|
||||
<p><EFBFBD> Copyright Ronald Garcia 2002. Permission to copy, use,
|
||||
modify, sell and distribute this document is granted provided this copyright
|
||||
notice appears in all copies. This document is provided "as is"
|
||||
without express or implied warranty, and with no claim as to its suitability for
|
||||
any purpose.</p>
|
||||
<p><EFBFBD> Copyright 2003 The Trustees of Indiana University.
|
||||
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)</p>
|
||||
|
||||
</body>
|
||||
|
||||
|
@@ -1,7 +1,8 @@
|
||||
// (C) Copyright Ronald Garcia 2002. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
// Copyright 2003 The Trustees of Indiana University.
|
||||
|
||||
// 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/shared_container_iterator.hpp"
|
||||
#include "boost/shared_ptr.hpp"
|
||||
|
@@ -1,7 +1,8 @@
|
||||
// (C) Copyright Ronald Garcia 2002. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
// Copyright 2003 The Trustees of Indiana University.
|
||||
|
||||
// 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/shared_container_iterator.hpp"
|
||||
#include "boost/shared_ptr.hpp"
|
||||
|
@@ -1,7 +1,8 @@
|
||||
// (C) Copyright Ronald Garcia 2002. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
// Copyright 2003 The Trustees of Indiana University.
|
||||
|
||||
// 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/shared_container_iterator.hpp"
|
||||
#include "boost/shared_ptr.hpp"
|
||||
|
@@ -1,7 +1,18 @@
|
||||
// (C) Copyright Ronald Garcia 2003. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
// Copyright 2003 The Trustees of Indiana University.
|
||||
|
||||
// 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)
|
||||
|
||||
// Shared container iterator adaptor
|
||||
// Author: Ronald Garcia
|
||||
// See http://boost.org/libs/utility/shared_container_iterator.html
|
||||
// for documentation.
|
||||
|
||||
//
|
||||
// shared_iterator_test.cpp - Regression tests for shared_container_iterator.
|
||||
//
|
||||
|
||||
|
||||
#include "boost/shared_container_iterator.hpp"
|
||||
#include "boost/shared_ptr.hpp"
|
||||
|
1
sublibs
Normal file
1
sublibs
Normal file
@@ -0,0 +1 @@
|
||||
The existance of this file tells the regression reporting programs that the directory contains sub-directories which are libraries.
|
38
test/Jamfile
38
test/Jamfile
@@ -6,8 +6,6 @@
|
||||
|
||||
# For more information, see http://www.boost.org/
|
||||
|
||||
|
||||
# Testing Jamfile autogenerated from XML source
|
||||
subproject libs/utility/test ;
|
||||
|
||||
# bring in rules for testing
|
||||
@@ -18,26 +16,28 @@ DEPENDS all : test ;
|
||||
|
||||
local test_monitor = <lib>@boost/libs/test/build/boost_test_exec_monitor ;
|
||||
|
||||
# Please keep the tests ordered by filename
|
||||
test-suite utility
|
||||
:
|
||||
[ run ../iterator_traits_test.cpp ]
|
||||
[ run ../iterators_test.cpp $(test_monitor) ]
|
||||
[ compile-fail ../noncopyable_test.cpp ]
|
||||
[ run ../numeric_traits_test.cpp ]
|
||||
[ run ../operators_test.cpp $(test_monitor) ]
|
||||
[ run ../binary_search_test.cpp $(test_monitor) ]
|
||||
:
|
||||
[ run ../addressof_test.cpp ]
|
||||
[ run ../assert_test.cpp ]
|
||||
[ run ../base_from_member_test.cpp ]
|
||||
[ run ../binary_search_test.cpp ]
|
||||
[ run ../call_traits_test.cpp : -u ]
|
||||
[ compile-fail ../checked_delete_test.cpp ]
|
||||
[ run ../compressed_pair_test.cpp $(test_monitor) : -u ]
|
||||
[ run ../addressof_test.cpp $(test_monitor) ]
|
||||
[ run ../current_function_test.cpp : : : <test-info>always_show_run_output ]
|
||||
[ run ../iterators_test.cpp $(test_monitor) ]
|
||||
[ run next_prior_test.cpp $(test_monitor) ]
|
||||
[ compile-fail ../noncopyable_test.cpp ]
|
||||
[ run ../numeric_traits_test.cpp ]
|
||||
[ run ../operators_test.cpp $(test_monitor) ]
|
||||
[ compile ../ref_ct_test.cpp ]
|
||||
[ run ../ref_test.cpp $(test_monitor) ]
|
||||
[ run ../enable_if_constructors.cpp $(test_monitor) ]
|
||||
[ run ../enable_if_dummy_arg_disambiguation.cpp $(test_monitor) ]
|
||||
[ run ../enable_if_lazy.cpp $(test_monitor) ]
|
||||
[ run ../enable_if_lazy_test.cpp $(test_monitor) ]
|
||||
[ run ../enable_if_member_templates.cpp $(test_monitor) ]
|
||||
[ run ../enable_if_namespace_disambiguation.cpp $(test_monitor) ]
|
||||
[ run ../enable_if_no_disambiguation.cpp $(test_monitor) ]
|
||||
[ run ../enable_if_partial_specializations.cpp $(test_monitor) ]
|
||||
[ run next_prior_test.cpp $(test_monitor) ]
|
||||
[ compile result_of_test.cpp ]
|
||||
[ run ../shared_iterator_test.cpp ]
|
||||
[ run ../value_init_test.cpp ]
|
||||
[ compile-fail ../value_init_test_fail1.cpp ]
|
||||
[ compile-fail ../value_init_test_fail2.cpp ]
|
||||
[ compile-fail ../value_init_test_fail3.cpp ]
|
||||
;
|
||||
|
@@ -9,25 +9,28 @@
|
||||
# bring in rules for testing
|
||||
import testing ;
|
||||
|
||||
# Please keep the tests ordered by filename
|
||||
test-suite utility
|
||||
:
|
||||
[ run ../iterator_traits_test.cpp ]
|
||||
[ run ../iterators_test.cpp ../../test/build//boost_test_exec_monitor ]
|
||||
[ compile-fail ../noncopyable_test.cpp ]
|
||||
[ run ../numeric_traits_test.cpp ]
|
||||
[ run ../operators_test.cpp ../../test/build//boost_test_exec_monitor ]
|
||||
[ run ../binary_search_test.cpp ../../test/build//boost_test_exec_monitor ]
|
||||
:
|
||||
[ run ../addressof_test.cpp ]
|
||||
[ run ../assert_test.cpp ]
|
||||
[ run ../base_from_member_test.cpp ]
|
||||
[ run ../binary_search_test.cpp ]
|
||||
[ run ../call_traits_test.cpp : -u ]
|
||||
[ compile-fail ../checked_delete_test.cpp ]
|
||||
[ run ../compressed_pair_test.cpp ../../test/build//boost_test_exec_monitor : -u ]
|
||||
[ run ../addressof_test.cpp ../../test/build//boost_test_exec_monitor ]
|
||||
[ run ../current_function_test.cpp : : : <test-info>always_show_run_output ]
|
||||
[ run ../iterators_test.cpp ../../test/build//boost_test_exec_monitor ]
|
||||
[ run next_prior_test.cpp ../../test/build//boost_test_exec_monitor ]
|
||||
[ compile-fail ../noncopyable_test.cpp ]
|
||||
[ run ../numeric_traits_test.cpp ]
|
||||
[ run ../operators_test.cpp ../../test/build//boost_test_exec_monitor ]
|
||||
[ compile ../ref_ct_test.cpp ]
|
||||
[ run ../ref_test.cpp ../../test/build//boost_test_exec_monitor ]
|
||||
[ run ../enable_if_constructors.cpp ../../test/build/boost_test_exec_monitor ]
|
||||
[ run ../enable_if_dummy_arg_disambiguation.cpp ../../test/build/boost_test_exec_monitor ]
|
||||
[ run ../enable_if_lazy.cpp ../../test/build/boost_test_exec_monitor ]
|
||||
[ run ../enable_if_lazy_test.cpp ../../test/build/boost_test_exec_monitor ]
|
||||
[ run ../enable_if_member_templates.cpp ../../test/build/boost_test_exec_monitor ]
|
||||
[ run ../enable_if_namespace_disambiguation.cpp ../../test/build/boost_test_exec_monitor ]
|
||||
[ run ../enable_if_no_disambiguation.cpp ../../test/build/boost_test_exec_monitor ]
|
||||
[ run ../enable_if_partial_specializations.cpp ../../test/build/boost_test_exec_monitor ]
|
||||
[ compile result_of_test.cpp ]
|
||||
[ run ../shared_iterator_test.cpp ]
|
||||
[ run ../value_init_test.cpp ]
|
||||
[ compile-fail ../value_init_test_fail1.cpp ]
|
||||
[ compile-fail ../value_init_test_fail2.cpp ]
|
||||
[ compile-fail ../value_init_test_fail3.cpp ]
|
||||
;
|
||||
|
53
test/result_of_test.cpp
Normal file
53
test/result_of_test.cpp
Normal file
@@ -0,0 +1,53 @@
|
||||
// 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)
|
||||
|
||||
// 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; };
|
||||
|
||||
struct int_result_of
|
||||
{
|
||||
template<typename F> struct result { typedef int type; };
|
||||
};
|
||||
|
||||
struct int_result_type_and_float_result_of
|
||||
{
|
||||
typedef int result_type;
|
||||
template<typename F> struct result { typedef float type; };
|
||||
};
|
||||
|
||||
struct X {};
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost;
|
||||
|
||||
typedef int (*func_ptr)(float, double);
|
||||
typedef int (&func_ref)(float, double);
|
||||
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;
|
||||
|
||||
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<int_result_of(void)>::type, void>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<result_of<const int_result_of(double)>::type, int>::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_type_and_float_result_of(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<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));
|
||||
return 0;
|
||||
}
|
@@ -8,7 +8,7 @@
|
||||
<table border="0" width="100%">
|
||||
<tr>
|
||||
<td width="277">
|
||||
<img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" width="277" height="86">
|
||||
<img src="../../boost.png" alt="boost.png (6897 bytes)" width="277" height="86">
|
||||
</td>
|
||||
<td align="middle">
|
||||
<h1>throw_exception.hpp</h1>
|
||||
|
@@ -1,223 +0,0 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
|
||||
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
|
||||
<meta name="ProgId" content="FrontPage.Editor.Document">
|
||||
<title>Transform Iterator Adaptor Documentation</title>
|
||||
</head>
|
||||
|
||||
<body bgcolor="#FFFFFF" text="#000000">
|
||||
|
||||
<img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)"
|
||||
align="center" width="277" height="86">
|
||||
|
||||
<h1>Transform Iterator Adaptor</h1>
|
||||
|
||||
Defined in header
|
||||
<a href="../../boost/iterator_adaptors.hpp">boost/iterator_adaptors.hpp</a>
|
||||
|
||||
<p>
|
||||
The transform iterator adaptor augments an iterator by applying some
|
||||
function object to the result of dereferencing the iterator. In other
|
||||
words, the <tt>operator*</tt> of the transform iterator first
|
||||
dereferences the base iterator, passes the result of this to the
|
||||
function object, and then returns the result. The following
|
||||
<b>pseudo-code</b> shows the basic idea:
|
||||
|
||||
<pre>
|
||||
value_type transform_iterator::operator*() const {
|
||||
return this->f(*this->base_iterator);
|
||||
}
|
||||
</pre>
|
||||
|
||||
All of the other operators of the transform iterator behave in the
|
||||
same fashion as those of the base iterator.
|
||||
|
||||
|
||||
<h2>Synopsis</h2>
|
||||
|
||||
<pre>
|
||||
namespace boost {
|
||||
template <class <a href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html">AdaptableUnaryFunction</a>, class BaseIterator>
|
||||
class transform_iterator_generator;
|
||||
|
||||
template <class <a href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html">AdaptableUnaryFunction</a>, class BaseIterator>
|
||||
typename transform_iterator_generator<AdaptableUnaryFunction,Iterator>::type
|
||||
make_transform_iterator(BaseIterator base, const AdaptableUnaryFunction& f = AdaptableUnaryFunction());
|
||||
}
|
||||
</pre>
|
||||
|
||||
<hr>
|
||||
|
||||
<h2><a name="transform_iterator_generator">The Transform Iterator Type
|
||||
Generator</a></h2>
|
||||
|
||||
The class <tt>transform_iterator_generator</tt> is a helper class whose
|
||||
purpose is to construct a transform iterator type. The template
|
||||
parameters for this class are the <tt>AdaptableUnaryFunction</tt> function object
|
||||
type and the <tt>BaseIterator</tt> type that is being wrapped.
|
||||
|
||||
<pre>
|
||||
template <class AdaptableUnaryFunction, class Iterator>
|
||||
class transform_iterator_generator
|
||||
{
|
||||
public:
|
||||
typedef <a href="./iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a><...> type;
|
||||
};
|
||||
</pre>
|
||||
|
||||
<h3>Example</h3>
|
||||
|
||||
<p>
|
||||
The following is an example of how to use the
|
||||
<tt>transform_iterator_generator</tt> class to iterate through a range
|
||||
of numbers, multiplying each of them by 2 when they are dereferenced.
|
||||
The <tt>boost::binder1st</tt> class is used instead of the standard
|
||||
one because tranform iterator requires the function object to be
|
||||
Default Constructible.
|
||||
|
||||
<p>
|
||||
<PRE>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <boost/iterator_adaptors.hpp>
|
||||
|
||||
// definition of class boost::binder1st and function boost::bind1st() ...
|
||||
|
||||
int
|
||||
main(int, char*[])
|
||||
{
|
||||
int x[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
|
||||
|
||||
typedef boost::binder1st< std::multiplies<int> > Function;
|
||||
typedef boost::transform_iterator_generator<Function, int*>::type doubling_iterator;
|
||||
|
||||
doubling_iterator i(x, boost::bind1st(std::multiplies<int>(), 2)),
|
||||
i_end(x + sizeof(x)/sizeof(int), boost::bind1st(std::multiplies<int>(), 2));
|
||||
|
||||
std::cout << "multiplying the array by 2:" << std::endl;
|
||||
while (i != i_end)
|
||||
std::cout << *i++ << " ";
|
||||
std::cout << std::endl;
|
||||
|
||||
// to be continued...
|
||||
</PRE>
|
||||
The output from this part is:
|
||||
<pre>
|
||||
2 4 6 8 10 12 14 16
|
||||
</pre>
|
||||
|
||||
<h3>Template Parameters</h3>
|
||||
|
||||
<Table border>
|
||||
<TR>
|
||||
<TH>Parameter</TH><TH>Description</TH>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><a
|
||||
href="http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html"><tt>AdaptableUnaryFunction</tt></a></TD>
|
||||
<TD>The function object that transforms each element in the iterator
|
||||
range. The <tt>argument_type</tt> of the function object must match
|
||||
the value type of the base iterator. The <tt>result_type</tt> of the
|
||||
function object will be the resulting iterator's
|
||||
<tt>value_type</tt>. If you want the resulting iterator to behave as
|
||||
an iterator, the result of the function should be solely a function of
|
||||
its argument. Also, the function object must be <a
|
||||
href="http://www.sgi.com/tech/stl/DefaultConstructible.html"> Default
|
||||
Constructible</a> (which many of the standard function objects are not).</TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD><tt>BaseIterator</tt></TD>
|
||||
<TD>The iterator type being wrapped. This type must at least be a model
|
||||
of the <a href="http://www.sgi.com/tech/stl/InputIterator">InputIterator</a> concept.</TD>
|
||||
</TR>
|
||||
|
||||
</Table>
|
||||
|
||||
<h3>Model of</h3>
|
||||
|
||||
The transform iterator adaptor (the type
|
||||
<tt>transform_iterator_generator<...>::type</tt>) is a model of <a
|
||||
href="http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a><a href="#1">[1]</a>.
|
||||
|
||||
|
||||
<h3>Members</h3>
|
||||
|
||||
The transform iterator type implements the member functions and
|
||||
operators required of the <a
|
||||
href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access Iterator</a>
|
||||
concept, except that the <tt>reference</tt> type is the same as the <tt>value_type</tt>
|
||||
so <tt>operator*()</tt> returns by-value. In addition it has the following constructor:
|
||||
|
||||
<pre>
|
||||
transform_iterator_generator::type(const BaseIterator& it,
|
||||
const AdaptableUnaryFunction& f = AdaptableUnaryFunction())
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
<hr>
|
||||
<p>
|
||||
|
||||
|
||||
<h2><a name="make_transform_iterator">The Transform Iterator Object Generator</a></h2>
|
||||
|
||||
<pre>
|
||||
template <class AdaptableUnaryFunction, class BaseIterator>
|
||||
typename transform_iterator_generator<AdaptableUnaryFunction,BaseIterator>::type
|
||||
make_transform_iterator(BaseIterator base,
|
||||
const AdaptableUnaryFunction& f = AdaptableUnaryFunction());
|
||||
</pre>
|
||||
|
||||
This function provides a convenient way to create transform iterators.
|
||||
|
||||
<h3>Example</h3>
|
||||
|
||||
Continuing from the previous example, we use the <tt>make_transform_iterator()</tt>
|
||||
function to add four to each element of the array.
|
||||
|
||||
<pre>
|
||||
std::cout << "adding 4 to each element in the array:" << std::endl;
|
||||
|
||||
std::copy(boost::make_transform_iterator(x, boost::bind1st(std::plus<int>(), 4)),
|
||||
boost::make_transform_iterator(x + N, boost::bind1st(std::plus<int>(), 4)),
|
||||
std::ostream_iterator<int>(std::cout, " "));
|
||||
std::cout << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
</pre>
|
||||
The output from this part is:
|
||||
<pre>
|
||||
5 6 7 8 9 10 11 12
|
||||
</pre>
|
||||
|
||||
<h3>Notes</h3>
|
||||
|
||||
|
||||
<a name="1">[1]</a> If the base iterator is a model of <a
|
||||
href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random Access Iterator</a>
|
||||
then the transform iterator will also suppport most of the
|
||||
functionality required by the Random Access Iterator concept. However, a
|
||||
transform iterator can never completely satisfy the requirements for
|
||||
<a
|
||||
href="http://www.sgi.com/tech/stl/ForwardIterator.html">Forward Iterator</a>
|
||||
(or of any concepts that refine Forward Iterator, which includes
|
||||
Random Access Iterator and Bidirectional Iterator) since the <tt>operator*</tt> of the transform
|
||||
iterator always returns by-value.
|
||||
|
||||
|
||||
|
||||
<hr>
|
||||
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->19 Aug 2001<!--webbot bot="Timestamp" endspan i-checksum="14767" --></p>
|
||||
<p><EFBFBD> Copyright Jeremy Siek 2000. Permission to copy, use,
|
||||
modify, sell and distribute this document is granted provided this copyright
|
||||
notice appears in all copies. This document is provided "as is"
|
||||
without express or implied warranty, and with no claim as to its suitability for
|
||||
any purpose.</p>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
@@ -1,76 +0,0 @@
|
||||
// (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify, sell and
|
||||
// distribute this software is granted provided this copyright notice appears
|
||||
// in all copies. This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
|
||||
#include <functional>
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <boost/iterator/transform_iterator.hpp>
|
||||
|
||||
// What a bummer. We can't use std::binder1st with transform iterator
|
||||
// because it does not have a default constructor. Here's a version
|
||||
// that does.
|
||||
|
||||
namespace boost {
|
||||
|
||||
template <class Operation>
|
||||
class binder1st
|
||||
: public std::unary_function<typename Operation::second_argument_type,
|
||||
typename Operation::result_type> {
|
||||
protected:
|
||||
Operation op;
|
||||
typename Operation::first_argument_type value;
|
||||
public:
|
||||
binder1st() { } // this had to be added!
|
||||
binder1st(const Operation& x,
|
||||
const typename Operation::first_argument_type& y)
|
||||
: op(x), value(y) {}
|
||||
typename Operation::result_type
|
||||
operator()(const typename Operation::second_argument_type& x) const {
|
||||
return op(value, x);
|
||||
}
|
||||
};
|
||||
|
||||
template <class Operation, class T>
|
||||
inline binder1st<Operation> bind1st(const Operation& op, const T& x) {
|
||||
typedef typename Operation::first_argument_type arg1_type;
|
||||
return binder1st<Operation>(op, arg1_type(x));
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
int
|
||||
main(int, char*[])
|
||||
{
|
||||
// This is a simple example of using the transform_iterators class to
|
||||
// generate iterators that multiply the value returned by dereferencing
|
||||
// the iterator. In this case we are multiplying by 2.
|
||||
// Would be cooler to use lambda library in this example.
|
||||
|
||||
int x[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
|
||||
const int N = sizeof(x)/sizeof(int);
|
||||
|
||||
typedef boost::binder1st< std::multiplies<int> > Function;
|
||||
typedef boost::transform_iterator<Function, int*> doubling_iterator;
|
||||
|
||||
doubling_iterator i(x, boost::bind1st(std::multiplies<int>(), 2)),
|
||||
i_end(x + N, boost::bind1st(std::multiplies<int>(), 2));
|
||||
|
||||
std::cout << "multiplying the array by 2:" << std::endl;
|
||||
while (i != i_end)
|
||||
std::cout << *i++ << " ";
|
||||
std::cout << std::endl;
|
||||
|
||||
std::cout << "adding 4 to each element in the array:" << std::endl;
|
||||
|
||||
std::copy(boost::make_transform_iterator(x, boost::bind1st(std::plus<int>(), 4)),
|
||||
boost::make_transform_iterator(x + N, boost::bind1st(std::plus<int>(), 4)),
|
||||
std::ostream_iterator<int>(std::cout, " "));
|
||||
std::cout << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
46
utility.htm
46
utility.htm
@@ -4,7 +4,7 @@
|
||||
<title>Header boost/utility.hpp Documentation</title>
|
||||
</head>
|
||||
<body bgcolor="#FFFFFF" text="#000000">
|
||||
<h1><img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align="center" WIDTH="277" HEIGHT="86">Header
|
||||
<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"><boost/utility.hpp></a></code>
|
||||
are in <code>namespace boost</code>.</p>
|
||||
@@ -22,6 +22,7 @@
|
||||
Class <a href="#Class_noncopyable">noncopyable</a></li>
|
||||
<li>
|
||||
Function template <a href="#addressof">addressof()</a></li>
|
||||
<li>Class template <a href="#result_of">result_of</a></li>
|
||||
</ul>
|
||||
<h2>
|
||||
Function templates <a name="checked_delete">checked_delete</a>() and
|
||||
@@ -136,11 +137,52 @@ void f() {
|
||||
// nonaddressable* xpe = &x; /* error */
|
||||
}</pre>
|
||||
</blockquote>
|
||||
<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. 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<F(T1, T2, ...,
|
||||
T<em>N</em>)>::type</code> defines the result type
|
||||
of the expression <code>f(t1, t2,
|
||||
...,t<em>N</em>)</code>. The implementation permits
|
||||
the type <code>F</code> to be a function pointer,
|
||||
function reference, member function pointer, or class
|
||||
type. When <code>F</code> is a class type with a
|
||||
member type <code>result_type</code>,
|
||||
<code>result_of<F(T1, T2, ...,
|
||||
T<em>N</em>)></code> is
|
||||
<code>F::result_type</code>. Otherwise,
|
||||
<code>result_of<F(T1, T2, ...,
|
||||
T<em>N</em>)></code> is <code>F::result<F(T1,
|
||||
T2, ..., T<em>N</em>)>::type</code> when
|
||||
<code><em>N</em> > 0</code> or <code>void</code>
|
||||
when <code><em>N</em> = 0</code>. For additional
|
||||
information about <code>result_of</code>, see the
|
||||
current draft of the C++ Library TR, <a
|
||||
href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2004/n1647.pdf">N1647</a>,
|
||||
or the <code>result_of</code> <a
|
||||
href="http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1454.html">proposal</a>.</p>
|
||||
|
||||
<p>Class template <code>result_of</code> resides in
|
||||
the header <code><<a
|
||||
href="../../boost/utility/result_of.hpp">boost/utility/result_of.hpp</a>></code>. By
|
||||
default, <em>N</em> may be any value between 0 and
|
||||
10. To change the upper limit, define the macro
|
||||
<code>BOOST_RESULT_OF_NUM_ARGS</code> to the maximum
|
||||
value for <em>N</em>.</p>
|
||||
|
||||
<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>. Contributed by Doug Gregor.</p>
|
||||
|
||||
<h2>Class templates for the Base-from-Member Idiom</h2>
|
||||
<p>See <a href="base_from_member.html">separate documentation</a>.</p>
|
||||
<hr>
|
||||
<p>Revised <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan
|
||||
-->23 December, 2003<!--webbot bot="Timestamp" endspan i-checksum="38582"
|
||||
-->02 May, 2004<!--webbot bot="Timestamp" endspan i-checksum="38582"
|
||||
-->
|
||||
</p>
|
||||
<p>© Copyright boost.org 1999-2003. Permission to copy, use, modify, sell and distribute
|
||||
|
@@ -8,15 +8,15 @@
|
||||
</head>
|
||||
<body vlink="#800080" link="#0000ff" text="#000000" bgcolor="#ffffff">
|
||||
|
||||
<h2><img src="../../c++boost.gif" width="276" height="86">
|
||||
<h2><img src="../../boost.png" width="276" height="86">
|
||||
Header <<a href="../../boost/utility/value_init.hpp">boost/utility/value_init.hpp</a>>
|
||||
</h2>
|
||||
|
||||
<h2>Contents</h2>
|
||||
|
||||
<dl>
|
||||
<dt><a href="#intro">Rationale</a></dt>
|
||||
<dt><a href="#rationale">Introduction</a></dt>
|
||||
<dt><a href="#rationale">Rationale</a></dt>
|
||||
<dt><a href="#intro">Introduction</a></dt>
|
||||
</dl>
|
||||
|
||||
<ul>
|
||||
@@ -49,7 +49,7 @@ a solution with consistent syntax for value initialization of scalar,
|
||||
union and class types. <br>
|
||||
</p>
|
||||
|
||||
<h2><a name="into"></a>Introduction</h2>
|
||||
<h2><a name="intro"></a>Introduction</h2>
|
||||
|
||||
<p>The C++ standard [<a href="#references">1</a>] contains the definitions
|
||||
of <code>zero-initialization</code> and <code>default-initialization</code>.
|
||||
@@ -131,7 +131,7 @@ data member:</p>
|
||||
|
||||
<h2><a name="val_init"><code>template class value_initialized<T></code></a></h2>
|
||||
|
||||
<pre>namespace boost {<br><br>template<class T><br>class value_initialized<br>{<br> public :<br> value_initialized() : x() {}<br> operator T&() const { return x ; }<br> T& data() const { return x ; }<br><br> private :<br> <i>impll-defined</i> x ;<br>} ;<br><br>template<class T><br>T const& get ( value_initialized<T> const& x )<br>{<br> return x.data() ;<br>}<br><br>template<class T><br>T& get ( value_initialized<T>& x )<br>{<br> return x.data() ;<br>}<br><br>} // namespace boost<br></pre>
|
||||
<pre>namespace boost {<br><br>template<class T><br>class value_initialized<br>{<br> public :<br> value_initialized() : x() {}<br> operator T&() const { return x ; }<br> T& data() const { return x ; }<br><br> private :<br> <i>unspecified</i> x ;<br>} ;<br><br>template<class T><br>T const& get ( value_initialized<T> const& x )<br>{<br> return x.data() ;<br>}<br><br>template<class T><br>T& get ( value_initialized<T>& x )<br>{<br> return x.data() ;<br>}<br><br>} // namespace boost<br></pre>
|
||||
|
||||
<p>An object of this template class is a <code>T</code>-wrapper convertible
|
||||
to <code>'T&'</code> whose wrapped object (data member of type <code>T</code>)
|
||||
|
@@ -1,13 +1,8 @@
|
||||
// (C) 2002, Fernando Luis Cacciola Carballal.
|
||||
//
|
||||
// This material is provided "as is", with absolutely no warranty expressed
|
||||
// or implied. Any use is at your own risk.
|
||||
//
|
||||
// Permission to use or copy this software for any purpose is hereby granted
|
||||
// without fee, provided the above notices are retained on all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted,
|
||||
// provided the above notices are retained, and a notice that the code was
|
||||
// modified is included with the above copyright notice.
|
||||
// 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"
|
||||
//
|
||||
@@ -22,8 +17,7 @@
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#define BOOST_INCLUDE_MAIN
|
||||
#include "boost/test/test_tools.hpp"
|
||||
#include "boost/test/minimal.hpp"
|
||||
|
||||
//
|
||||
// Sample POD type
|
||||
@@ -70,34 +64,28 @@ template<class T>
|
||||
void test ( T const& y, T const& z )
|
||||
{
|
||||
boost::value_initialized<T> x ;
|
||||
BOOST_TEST ( y == x ) ;
|
||||
BOOST_TEST ( y == get(x) ) ;
|
||||
BOOST_CHECK ( y == x ) ;
|
||||
BOOST_CHECK ( y == boost::get(x) ) ;
|
||||
static_cast<T&>(x) = z ;
|
||||
get(x) = z ;
|
||||
BOOST_TEST ( x == z ) ;
|
||||
boost::get(x) = z ;
|
||||
BOOST_CHECK ( x == z ) ;
|
||||
|
||||
boost::value_initialized<T> const x_c ;
|
||||
BOOST_TEST ( y == x_c ) ;
|
||||
BOOST_TEST ( y == get(x_c) ) ;
|
||||
static_cast<T&>(x_c) = z ;
|
||||
BOOST_TEST ( x_c == z ) ;
|
||||
#ifdef PRODUCE_ERROR_1
|
||||
get(x_c) = z ; // this should produce an ERROR
|
||||
#endif
|
||||
BOOST_CHECK ( y == x_c ) ;
|
||||
BOOST_CHECK ( y == boost::get(x_c) ) ;
|
||||
T& x_c_ref = x_c ;
|
||||
x_c_ref = z ;
|
||||
BOOST_CHECK ( x_c == z ) ;
|
||||
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
|
||||
boost::value_initialized<T const> cx ;
|
||||
BOOST_TEST ( y == cx ) ;
|
||||
BOOST_TEST ( y == get(cx) ) ;
|
||||
#ifdef PRODUCE_ERROR_2
|
||||
get(cx) = z ; // this should produce an ERROR
|
||||
#endif
|
||||
BOOST_CHECK ( y == cx ) ;
|
||||
BOOST_CHECK ( y == boost::get(cx) ) ;
|
||||
|
||||
boost::value_initialized<T const> const cx_c ;
|
||||
BOOST_TEST ( y == cx_c ) ;
|
||||
BOOST_TEST ( y == get(cx_c) ) ;
|
||||
#ifdef PRODUCE_ERROR_3
|
||||
get(cx_c) = z ; // this should produce an ERROR
|
||||
#endif
|
||||
BOOST_CHECK ( y == cx_c ) ;
|
||||
BOOST_CHECK ( y == boost::get(cx_c) ) ;
|
||||
#endif
|
||||
}
|
||||
|
||||
int test_main(int, char **)
|
||||
|
37
value_init_test_fail1.cpp
Normal file
37
value_init_test_fail1.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
// (C) 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
|
||||
|
||||
#include "boost/test/minimal.hpp"
|
||||
|
||||
int test_main(int, char **)
|
||||
{
|
||||
boost::value_initialized<int> const x_c ;
|
||||
|
||||
get(x_c) = 1234 ; // this should produce an ERROR
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
unsigned int expected_failures = 0;
|
||||
|
||||
|
||||
|
||||
|
||||
|
36
value_init_test_fail2.cpp
Normal file
36
value_init_test_fail2.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
// (C) 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
|
||||
|
||||
#include "boost/test/minimal.hpp"
|
||||
|
||||
int test_main(int, char **)
|
||||
{
|
||||
boost::value_initialized<int const> cx ;
|
||||
|
||||
get(cx) = 1234 ; // this should produce an ERROR
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int expected_failures = 0;
|
||||
|
||||
|
||||
|
||||
|
||||
|
37
value_init_test_fail3.cpp
Normal file
37
value_init_test_fail3.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
// (C) 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
|
||||
|
||||
#include "boost/test/minimal.hpp"
|
||||
|
||||
int test_main(int, char **)
|
||||
{
|
||||
boost::value_initialized<int const> const cx_c ;
|
||||
|
||||
get(cx_c) = 1234 ; // this should produce an ERROR
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
unsigned int expected_failures = 0;
|
||||
|
||||
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user