Compare commits

...

82 Commits

Author SHA1 Message Date
cfb38f7097 This commit was manufactured by cvs2svn to create branch
'python-v2-dev'.

[SVN r14785]
2002-08-12 13:35:54 +00:00
4ba6a96822 fix test_main signature
[SVN r14783]
2002-08-12 13:22:40 +00:00
1ea4140d56 Added tests for BOOST_NO_STD_ITERATOR_TRAITS
[SVN r14654]
2002-07-31 11:25:25 +00:00
351d4ecb15 Document policies() member of iterator_adaptor
[SVN r14613]
2002-07-26 00:03:24 +00:00
7fbf84dcc6 BaseType -> Base in one more place
[SVN r14605]
2002-07-25 19:10:05 +00:00
3ff49b272d fixup
[SVN r14598]
2002-07-25 14:16:54 +00:00
5b52e3d418 Fix doc based on Beman's feedback
[SVN r14596]
2002-07-25 13:52:48 +00:00
8c0eb498d3 Fix unversioned VC++ checks
[SVN r14436]
2002-07-13 12:26:19 +00:00
48a81ef7ea VC++ fixes
[SVN r14435]
2002-07-13 12:22:51 +00:00
f7610c9b26 fix link
[SVN r14318]
2002-07-05 23:51:20 +00:00
1755eaf019 Merged from RC_1_28_0
[SVN r13944]
2002-05-16 00:56:42 +00:00
6b8b218efb Removed tabs, fixed end of files.
[SVN r13803]
2002-05-10 11:35:38 +00:00
333d79b345 Add index.html so automatic tools work correctly
[SVN r13725]
2002-05-07 19:23:05 +00:00
f0fa436fe4 Added new config macro BOOST_HAS_MS_INT64 to detect presence of __int64 data type.
Modified boost source to use BOOST_HAS_LONG_LONG and BOOST_HAS_MS_INT64
   where appropriate to do so.


[SVN r13714]
2002-05-07 11:24:29 +00:00
13e6d78fa8 Fixes for Borland C++ Builder 6
[SVN r13662]
2002-05-04 11:03:42 +00:00
7126ea2685 Borland C++ Builder 6 fixes
[SVN r13659]
2002-05-04 10:55:15 +00:00
a37518cb4a Fixed broken links.
[SVN r13574]
2002-04-27 11:05:49 +00:00
64b3e8c3bd add missing #include <iterator>
[SVN r13554]
2002-04-23 19:52:11 +00:00
339937380e MSVC fixes.
[SVN r13476]
2002-04-13 13:19:57 +00:00
6156f0d302 Roll addressof() patch back in!
[SVN r13433]
2002-04-10 17:01:35 +00:00
00560e8e17 addressof.hpp:
- Peter Dimov suggested a fix to deal with those evil cv-qualifiers


[SVN r13431]
2002-04-10 14:47:32 +00:00
029ff9828f Roll back addressof() patch temporarily
[SVN r13428]
2002-04-10 09:48:30 +00:00
ec188c7c3e Make local classes nonlocal to silence annoying warnings from Borland C++
[SVN r13418]
2002-04-10 04:00:22 +00:00
0a0296a5d0 ref.hpp:
- Use addressof() instead of & operator


[SVN r13416]
2002-04-10 03:36:17 +00:00
6e26a5bbe7 boost/utility.hpp:
- Include boost/utility/addressof.hpp

boost/utility/addressof.hpp:
  - addressof() implementation

libs/utility/utility.htm:
  - Document addressof

libs/utility/addressof_test.cpp:
  - Test addressof()


[SVN r13414]
2002-04-10 03:31:18 +00:00
dc1b6246a0 boost/ref.hpp:
- Added get_pointer method to return a pointer (instead of a reference)

libs/bind/ref.html:
  - Document get_pointer


[SVN r13322]
2002-03-31 00:24:00 +00:00
15f69eaf14 Fixed new problem with Borland compile -
code clashes with some new type traits workarounds for some reason.


[SVN r13226]
2002-03-19 11:33:00 +00:00
4774a0d325 Added Copyright
[SVN r13145]
2002-03-09 20:34:06 +00:00
be78ab72c9 update expected failures for Sun CC
[SVN r13101]
2002-03-05 20:41:37 +00:00
0bc4a1b20d Warning suppressioni from Craig Rodrigues
[SVN r13098]
2002-03-05 18:55:49 +00:00
c8b674d105 Add missing paren.
[SVN r12997]
2002-03-01 17:43:00 +00:00
b421d4725a Fixed expected failures for gcc 3.1
[SVN r12994]
2002-03-01 12:27:01 +00:00
1662bb5713 use of "small" changed to "small_" to suppress confusion on some compilers
[SVN r12916]
2002-02-24 02:35:19 +00:00
ad79a21abd added portability note about using std::vector's as Base with VC++
[SVN r12875]
2002-02-21 12:09:46 +00:00
19645a52e6 Added a default constructor to shared_count and shared_ptr for incomplete types (void).
[SVN r12815]
2002-02-15 13:31:58 +00:00
74c3077c9a Added test cases for incomplete and abstract base class types.
[SVN r12803]
2002-02-14 12:57:32 +00:00
1f29191329 Modified call_traits to work with incomplete types.
[SVN r12800]
2002-02-14 12:54:57 +00:00
4b636a7680 Always say "private noncopyable" to avoid warnings.
[SVN r12762]
2002-02-08 20:08:15 +00:00
e6fc2555f3 removed tabs
[SVN r12707]
2002-02-04 20:29:35 +00:00
e27d0fcf2a New smart pointer documentation. Related clean-up of the smart pointer
library. Changing includes to include the new individual smart pointer
headers. Replacing old smart pointer library with an include of the new
smart pointer headers. Simplify ifdefs that involve the member templates
macros now that BOOST_MSVC6_MEMBER_TEMPLATES is also guaranteed to bet
set for platforms that have full member templates.


[SVN r12647]
2002-02-02 18:36:12 +00:00
2643c33b20 Doc fixes from Thomas Witt
[SVN r12621]
2002-02-01 13:03:21 +00:00
71af1e77c8 compile-time ref.hpp header test, initial checkin
[SVN r12525]
2002-01-27 13:39:06 +00:00
99e7406bd9 ref_ct_test.cpp
[SVN r12524]
2002-01-27 13:32:37 +00:00
413265f497 compile-time ref.hpp header test, initial checkin
[SVN r12522]
2002-01-27 13:07:20 +00:00
fe44cdf09b made 'reference_wrapper' Assignable
[SVN r12520]
2002-01-27 13:02:27 +00:00
e413428d71 Added tests for the new smart pointers.
[SVN r12500]
2002-01-25 13:54:30 +00:00
88b9822db7 Mark inline to avoid warning with "require prototypes" on.
[SVN r12490]
2002-01-24 19:15:30 +00:00
24045c0cd7 #included <boost/checked_delete.hpp>, removed unnecessary #includes.
[SVN r12488]
2002-01-24 17:47:08 +00:00
d2aa9f4a84 added missing #include of boost/config.hpp
[SVN r12483]
2002-01-24 16:55:41 +00:00
d2a5fd169f initial checkin
[SVN r12481]
2002-01-24 16:52:06 +00:00
4e350d9934 Modified is_reference_wrapper<> to work for reference types.
[SVN r12475]
2002-01-24 13:28:08 +00:00
f3f697bbc8 added is_reference_wrapper<>, unwrap_reference<>
[SVN r12470]
2002-01-23 21:19:14 +00:00
c7c09696db Tweak comments. Include <assert.h> and <boost/current_function.hpp> only
when needed.


[SVN r12446]
2002-01-22 18:28:33 +00:00
dbcc58d984 Smart pointer enhancements, initial commit
[SVN r12439]
2002-01-22 13:38:52 +00:00
8231310c4d initial checkin
[SVN r12390]
2002-01-21 01:29:06 +00:00
2988140430 tabs
[SVN r12360]
2002-01-19 16:07:28 +00:00
7387966005 Stripped tabs from source
[SVN r12351]
2002-01-19 12:38:14 +00:00
e0a5a61375 removed eroneous "detail::" prefix
[SVN r12326]
2002-01-15 19:14:53 +00:00
66ecd70689 removed std:: prefix from slist
[SVN r12310]
2002-01-14 14:57:20 +00:00
67f4f45653 Fixed violation of 'explicit' constructor
[SVN r12256]
2002-01-09 13:15:54 +00:00
1bf28b3de2 Fixes for Borland
[SVN r12254]
2002-01-09 12:11:37 +00:00
eb3c3435d7 Updated expected results
[SVN r12250]
2002-01-08 13:01:15 +00:00
8a81d8b16c Workarounds for MSVC
[SVN r12246]
2002-01-07 19:24:45 +00:00
bc9d8b13d0 converted some of the old terminology (OrderIterator) to the current
terminology (IndexIterator)


[SVN r12164]
2001-12-28 15:49:45 +00:00
4768b167ab Removed obsolete mentions of "less"; Added formalized Policies Concept description
[SVN r12056]
2001-12-14 12:54:21 +00:00
591ff70ed1 many fixes
[SVN r12054]
2001-12-13 19:43:35 +00:00
7bf2ad0b22 VC6 patch
[SVN r12045]
2001-12-13 18:24:29 +00:00
409c79b2e4 fix example (thanks to Michael Stevens)
[SVN r11979]
2001-12-08 08:39:27 +00:00
d0410691a1 removed calls to non-standard std::iota (SGI extension)
[SVN r11904]
2001-12-04 08:02:36 +00:00
64e5115138 Fixed spelling error ing gcc-3.0 bug workaround
[SVN r11888]
2001-12-03 21:48:54 +00:00
7ae912d83c Rolled in Helmut's fixes for random_access_iterable; rolled back
workarounds for that problem.


[SVN r11887]
2001-12-03 21:47:58 +00:00
2937f5876c changed std::iota call (SGI extension) to a manual loop
in permutation_iterator test


[SVN r11869]
2001-12-03 08:35:08 +00:00
8619c9b5c3 fix gcc looping (from Dave Abrahams)
[SVN r11839]
2001-11-30 17:55:39 +00:00
e4d5684f6b added test for permutation_iterator
[SVN r11825]
2001-11-30 11:10:07 +00:00
3d69cf95da added documentation for the permutation_iterator_adaptor
and linked to it from the iterator_adaptors documentation.


[SVN r11824]
2001-11-30 10:40:03 +00:00
18944572b7 committing Daryle and Helmut's changes
[SVN r11813]
2001-11-29 21:22:52 +00:00
3e9d0f80c2 add generator iterator adaptor
[SVN r11736]
2001-11-19 22:11:51 +00:00
a2c4d1990a add boost::generator_iterator_policies and convenience classes
[SVN r11725]
2001-11-18 17:56:43 +00:00
404261c6ee add definition for integral constants initialized in-class
[SVN r11723]
2001-11-18 17:32:19 +00:00
87abc59612 #undef BOOST_REF_CONST added
[SVN r11674]
2001-11-14 14:40:29 +00:00
cb98ddf7db Fixed a bug w/ adaptable function objects + nested binds, made ref<> return const
[SVN r11670]
2001-11-13 13:56:05 +00:00
7d2e6c9025 __stdcall support added.
[SVN r11649]
2001-11-10 19:18:58 +00:00
45 changed files with 2484 additions and 302 deletions

46
addressof_test.cpp Normal file
View File

@ -0,0 +1,46 @@
// Copyright (C) 2002 Brad King (brad.king@kitware.com)
// Doug 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.
// For more information, see http://www.boost.org
#define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp>
#include <boost/utility.hpp>
struct useless_type {};
class nonaddressable {
public:
void dummy(); // Silence GCC warning: all member of class are private
private:
useless_type operator&() const;
};
int test_main(int, char*[])
{
nonaddressable* px = new nonaddressable();
nonaddressable& x = *px;
BOOST_TEST(boost::addressof(x) == px);
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;
}

33
assert_test.cpp Normal file
View File

@ -0,0 +1,33 @@
#if defined(_MSC_VER) && !defined(__ICL)
#pragma warning(disable: 4786) // identifier truncated in debug info
#pragma warning(disable: 4710) // function not inlined
#pragma warning(disable: 4711) // function selected for automatic inline expansion
#pragma warning(disable: 4514) // unreferenced inline removed
#endif
//
// assert_test.cpp - a test for boost/assert.hpp
//
// 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.
//
#define BOOST_DEBUG 1
#include <boost/assert.hpp>
#include <cstdio>
bool boost_error(char const * expr, char const * func, char const * file, long line)
{
std::printf("%s(%ld): Assertion '%s' failed in function '%s'\n", file, line, expr, func);
return true; // fail w/ standard assert()
}
int main()
{
BOOST_ASSERT(0 == 1);
}

View File

@ -57,7 +57,7 @@ struct object_id_compare
// A singleton of this type coordinates the acknowledgements
// of objects being created and used.
class object_registrar
: boost::noncopyable
: private boost::noncopyable
{
public:

249
binary_search_test.cpp Normal file
View File

@ -0,0 +1,249 @@
// (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.
#include <vector>
#include <string>
#include <memory>
#include <climits>
#include <iostream>
#include <cassert>
#include <stdlib.h> // for rand(). Would use cstdlib but VC6.4 doesn't put it in std::
#include <list>
#include <algorithm>
#include <boost/detail/binary_search.hpp>
#if defined(__SGI_STL_PORT) ? defined(__SGI_STL_OWN_IOSTREAMS) : (!defined(__GNUC__) || __GNUC__ > 2)
# define USE_SSTREAM
#endif
#ifdef USE_SSTREAM
# include <sstream>
#else
# include <strstream>
#endif
namespace {
typedef std::vector<std::string> string_vector;
const std::size_t sequence_length = 1000;
unsigned random_number()
{
return static_cast<unsigned>(::rand()) % sequence_length;
}
# ifndef USE_SSTREAM
class unfreezer {
public:
unfreezer(std::ostrstream& s) : m_stream(s) {}
~unfreezer() { m_stream.freeze(false); }
private:
std::ostrstream& m_stream;
};
# endif
template <class T>
void push_back_random_number_string(T& seq)
{
unsigned value = random_number();
# if defined(__SGI_STL_PORT) ? defined(__SGI_STL_OWN_IOSTREAMS) : (!defined(__GNUC__) || __GNUC__ > 2)
std::ostringstream s;
s << value;
seq.push_back(s.str());
# else
std::ostrstream s;
auto unfreezer unfreeze(s);
s << value << char(0);
seq.push_back(std::string(s.str()));
# endif
}
inline unsigned to_int(unsigned x) { return x; }
inline unsigned to_int(const std::string& x) { return atoi(x.c_str()); }
struct cmp
{
template <class A1, class A2>
inline bool operator()(const A1& a1, const A2& a2) const
{
return to_int(a1) < to_int(a2);
}
};
inline bool operator<(const std::string& x, const unsigned y)
{
return to_int(x) < y;
}
inline bool operator<(const unsigned y, const std::string& x)
{
return y < to_int(x);
}
template <class T> void sort_by_value(T&);
template <>
void sort_by_value(std::vector<std::string>& v)
{
std::sort(v.begin(), v.end(), cmp());
}
template <class T>
void random_sorted_sequence(T& seq)
{
seq.clear();
for (std::size_t i = 0; i < sequence_length; ++i)
{
push_back_random_number_string(seq);
}
sort_by_value(seq);
}
# if defined(BOOST_MSVC) && BOOST_MSVC < 1300 && !defined(__SGI_STL_PORT)
// VC6's standard lib doesn't have a template member function for list::sort()
template <>
void random_sorted_sequence(std::list<std::string>& result)
{
std::vector<std::string> seq;
seq.reserve(sequence_length);
for (std::size_t i = 0; i < sequence_length; ++i)
{
push_back_random_number_string(seq);
}
sort_by_value(seq);
result.resize(seq.size());
std::copy(seq.begin(), seq.end(), result.begin());
}
#else
template <>
inline void sort_by_value(std::list<std::string>& l)
{
l.sort(cmp());
}
# endif
// A way to select the comparisons with/without a Compare parameter for testing.
template <class Compare> struct searches
{
template <class Iterator, class Key>
static Iterator lower_bound(Iterator start, Iterator finish, Key key, Compare cmp)
{ return boost::detail::lower_bound(start, finish, key, cmp); }
template <class Iterator, class Key>
static Iterator upper_bound(Iterator start, Iterator finish, Key key, Compare cmp)
{ return boost::detail::upper_bound(start, finish, key, cmp); }
template <class Iterator, class Key>
static std::pair<Iterator, Iterator> equal_range(Iterator start, Iterator finish, Key key, Compare cmp)
{ return boost::detail::equal_range(start, finish, key, cmp); }
template <class Iterator, class Key>
static bool binary_search(Iterator start, Iterator finish, Key key, Compare cmp)
{ return boost::detail::binary_search(start, finish, key, cmp); }
};
struct no_compare {};
template <> struct searches<no_compare>
{
template <class Iterator, class Key>
static Iterator lower_bound(Iterator start, Iterator finish, Key key, no_compare)
{ return boost::detail::lower_bound(start, finish, key); }
template <class Iterator, class Key>
static Iterator upper_bound(Iterator start, Iterator finish, Key key, no_compare)
{ return boost::detail::upper_bound(start, finish, key); }
template <class Iterator, class Key>
static std::pair<Iterator, Iterator> equal_range(Iterator start, Iterator finish, Key key, no_compare)
{ return boost::detail::equal_range(start, finish, key); }
template <class Iterator, class Key>
static bool binary_search(Iterator start, Iterator finish, Key key, no_compare)
{ return boost::detail::binary_search(start, finish, key); }
};
template <class Sequence, class Compare>
void test_loop(Sequence& x, Compare cmp, unsigned long test_count)
{
typedef typename Sequence::const_iterator const_iterator;
for (unsigned long i = 0; i < test_count; ++i)
{
random_sorted_sequence(x);
const const_iterator start = x.begin();
const const_iterator finish = x.end();
unsigned key = random_number();
const const_iterator l = searches<Compare>::lower_bound(start, finish, key, cmp);
const const_iterator u = searches<Compare>::upper_bound(start, finish, key, cmp);
bool found_l = false;
bool found_u = false;
std::size_t index = 0;
std::size_t count = 0;
unsigned last_value = 0;
for (const_iterator p = start; p != finish; ++p)
{
if (p == l)
found_l = true;
if (p == u)
{
assert(found_l);
found_u = true;
}
unsigned value = to_int(*p);
assert(value >= last_value);
last_value = value;
if (!found_l)
{
++index;
assert(to_int(*p) < key);
}
else if (!found_u)
{
++count;
assert(to_int(*p) == key);
}
else
assert(to_int(*p) > key);
}
assert(found_l || l == finish);
assert(found_u || u == finish);
std::pair<const_iterator, const_iterator>
range = searches<Compare>::equal_range(start, finish, key, cmp);
assert(range.first == l);
assert(range.second == u);
bool found = searches<Compare>::binary_search(start, finish, key, cmp);
assert(found == (u != l));
std::cout << "found " << count << " copies of " << key << " at index " << index << "\n";
}
}
}
int main()
{
std::vector<std::string> x;
std::cout << "=== testing random-access iterators with <: ===\n";
test_loop(x, no_compare(), 25);
std::cout << "=== testing random-access iterators with compare: ===\n";
test_loop(x, cmp(), 25);
std::list<std::string> y;
std::cout << "=== testing bidirectional iterators with <: ===\n";
test_loop(y, no_compare(), 25);
std::cout << "=== testing bidirectional iterators with compare: ===\n";
test_loop(y, cmp(), 25);
std::cerr << "******TEST PASSED******\n";
return 0;
}

View File

@ -5,7 +5,7 @@
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 4.0">
<meta name="GENERATOR" content="Microsoft FrontPage Express 2.0">
<title>Call Traits</title>
</head>
@ -592,7 +592,8 @@ would prevent template argument deduction from functioning.</p>
<p>The call_traits template will &quot;optimize&quot; the passing
of a small built-in type as a function parameter, this mainly has
an effect when the parameter is used within a loop body. In the
following example (see <a href="algo_opt_examples.cpp">algo_opt_examples.cpp</a>),
following example (see <a
href="../type_traits/examples/fill_example.cpp">fill_example.cpp</a>),
a version of std::fill is optimized in two ways: if the type
passed is a single byte built-in type then std::memset is used to
effect the fill, otherwise a conventional C++ implemention is
@ -751,7 +752,8 @@ Hinnant and John Maddock.</p>
<p>Maintained by <a href="mailto:John_Maddock@compuserve.com">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>
discussion list at <a
href="http://www.yahoogroups.com/list/boost">www.yahoogroups.com/list/boost</a>.</p>
<p>.</p>

View File

@ -6,6 +6,8 @@
// warranty, and with no claim as to its suitability for any purpose.
// standalone test program for <boost/call_traits.hpp>
// 18 Mar 2002:
// Changed some names to prevent conflicts with some new type_traits additions.
// 03 Oct 2000:
// Enabled extra tests for VC6.
@ -78,7 +80,7 @@ struct contained<T[N]>
#endif
template <class T>
contained<typename boost::call_traits<T>::value_type> wrap(const T& t)
contained<typename boost::call_traits<T>::value_type> test_wrap_type(const T& t)
{
typedef typename boost::call_traits<T>::value_type ct;
return contained<ct>(t);
@ -204,7 +206,7 @@ int main(int argc, char *argv[ ])
c2(i);
int* pi = &i;
int a[2] = {1,2};
#if (defined(BOOST_MSVC6_MEMBER_TEMPLATES) || !defined(BOOST_NO_MEMBER_TEMPLATES)) && !defined(__ICL)
#if defined(BOOST_MSVC6_MEMBER_TEMPLATES) && !defined(__ICL)
call_traits_checker<int*> c3;
c3(pi);
call_traits_checker<int&> c4;
@ -217,9 +219,9 @@ int main(int argc, char *argv[ ])
#endif
#endif
check_wrap(wrap(2), 2);
check_wrap(test_wrap_type(2), 2);
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__SUNPRO_CC)
check_wrap(wrap(a), a);
check_wrap(test_wrap_type(a), a);
check_make_pair(test::make_pair(a, a), a, a);
#endif
@ -240,12 +242,12 @@ int main(int argc, char *argv[ ])
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)
#if defined(BOOST_MSVC6_MEMBER_TEMPLATES) || !defined(BOOST_NO_MEMBER_TEMPLATES)
#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)
#if !(defined(__GNUC__) && (__GNUC__ < 4))
#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)
@ -268,16 +270,26 @@ int main(int argc, char *argv[ ])
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)
// 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)
#else
std::cout << "You're compiler does not support partial template instantiation, skipping 8 tests (8 errors)" << std::endl;
failures += 8;
test_count += 8;
std::cout << "You're compiler does not support partial template specialiation, skipping 8 tests (8 errors)" << std::endl;
failures += 12;
test_count += 12;
#endif
#else
std::cout << "You're compiler does not support partial template instantiation, skipping 20 tests (20 errors)" << std::endl;
failures += 20;
test_count += 20;
std::cout << "You're compiler does not support partial template specialiation, skipping 20 tests (20 errors)" << std::endl;
failures += 24;
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)
return check_result(argc, argv);
}
@ -388,7 +400,7 @@ void call_traits_test<T, true>::assert_construct(typename boost::call_traits<T>:
template struct call_traits_test<int>;
template struct call_traits_test<const int>;
template struct call_traits_test<int*>;
#if defined(BOOST_MSVC6_MEMBER_TEMPLATES) || !defined(BOOST_NO_MEMBER_TEMPLATES)
#if defined(BOOST_MSVC6_MEMBER_TEMPLATES)
template struct call_traits_test<int&>;
template struct call_traits_test<const int&>;
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__SUNPRO_CC)
@ -397,24 +409,22 @@ template struct call_traits_test<int[2], true>;
#endif
#ifdef BOOST_MSVC
unsigned int expected_failures = 10;
unsigned int expected_failures = 14;
#elif defined(__SUNPRO_CC)
#if(__SUNPRO_CC <= 0x520)
unsigned int expected_failures = 14;
#elif(__SUNPRO_CC <= 0x530)
unsigned int expected_failures = 13;
unsigned int expected_failures = 18;
#elif(__SUNPRO_CC < 0x530)
unsigned int expected_failures = 17;
#else
unsigned int expected_failures = 6;
#endif
#elif defined(__BORLANDC__)
unsigned int expected_failures = 2;
#elif defined(__GNUC__)
#elif (defined(__GNUC__) && ((__GNUC__ < 3) || (__GNUC__ == 3) && (__GNUC_MINOR__ < 1)))
unsigned int expected_failures = 4;
#elif defined(__HP_aCC)
unsigned int expected_failures = 24;
#else
unsigned int expected_failures = 0;
#endif

View File

@ -329,7 +329,7 @@ void compressed_pair_array_tester<T1, T2>::test(first_param_type p1, second_para
BOOST_TEST(sizeof(T2) == sizeof(cp1.second()));
}
int test_main(int, char **)
int test_main(int, char *[])
{
// declare some variables to pass to the tester:
non_empty1 ne1(2);

View File

@ -22,8 +22,8 @@ int main(int, char*[])
// 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, " "));
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.
@ -31,23 +31,26 @@ int main(int, char*[])
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::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
#if !defined(BOOST_MSVC) || (BOOST_MSVC > 1200)
std::copy(boost::make_counting_iterator(numbers.begin()),
boost::make_counting_iterator(numbers.end()),
std::back_inserter(pointers));
boost::make_counting_iterator(numbers.end()),
std::back_inserter(pointers));
#endif
#if !defined(BOOST_MSVC) || (BOOST_MSVC > 1300)
// Use indirect iterator to print out numbers by accessing
// them through the array of pointers.
#ifndef BOOST_MSVC
std::cout << "indirectly printing out the numbers from 0 to "
<< N << std::endl;
<< N << std::endl;
std::copy(boost::make_indirect_iterator(pointers.begin()),
boost::make_indirect_iterator(pointers.end()),
std::ostream_iterator<int>(std::cout, " "));
boost::make_indirect_iterator(pointers.end()),
std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
#endif
return 0;

View File

@ -27,7 +27,9 @@
#include <climits>
#include <iterator>
#include <stdlib.h>
#include <boost/tuple/tuple.hpp>
#ifndef __BORLANDC__
# include <boost/tuple/tuple.hpp>
#endif
#include <vector>
#include <list>
#include <cassert>
@ -72,8 +74,12 @@ void category_test(
// Try some binary searches on the range to show that it's ordered
assert(std::binary_search(start, finish, *internal));
CountingIterator x,y;
boost::tie(x,y) = std::equal_range(start, finish, *internal);
// #including tuple crashed borland, so I had to give up on tie().
std::pair<CountingIterator,CountingIterator> xy(
std::equal_range(start, finish, *internal));
CountingIterator x = xy.first, y = xy.second;
assert(boost::detail::distance(x, y) == 1);
// Show that values outside the range can't be found
@ -234,14 +240,14 @@ int main()
test_integer<unsigned int>();
test_integer<long>();
test_integer<unsigned long>();
#if defined(ULLONG_MAX) || defined(ULONG_LONG_MAX)
#if defined(BOOST_HAS_LONG_LONG)
test_integer<long long>();
test_integer<unsigned long long>();
#endif
// wrapping an iterator or non-built-in integer type causes an INTERNAL
// COMPILER ERROR in MSVC without STLport. I'm clueless as to why.
#if !defined(BOOST_MSVC) || defined(__SGI_STL_PORT)
#if !defined(BOOST_MSVC) || BOOST_MSVC > 1200 || defined(__SGI_STL_PORT)
// Test user-defined type.
test_integer<my_int1>();
test_integer<my_int2>();
@ -253,7 +259,7 @@ int main()
# ifndef BOOST_NO_SLIST
test_container<BOOST_STD_EXTENSION_NAMESPACE::slist<int> >();
# endif
// Also prove that we can handle raw pointers.
int array[2000];
test(boost::make_counting_iterator(array), boost::make_counting_iterator(array+2000-1));

32
current_function_test.cpp Normal file
View File

@ -0,0 +1,32 @@
#if defined(_MSC_VER) && !defined(__ICL)
#pragma warning(disable: 4786) // identifier truncated in debug info
#pragma warning(disable: 4710) // function not inlined
#pragma warning(disable: 4711) // function selected for automatic inline expansion
#pragma warning(disable: 4514) // unreferenced inline removed
#endif
//
// current_function_test.cpp - a test for boost/current_function.hpp
//
// 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.
//
#include <boost/current_function.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);
}
#define MESSAGE(msg) message(__FILE__, __LINE__, BOOST_CURRENT_FUNCTION, msg)
int main()
{
MESSAGE("assertion failed");
}

View File

@ -195,7 +195,7 @@ The policies type has only one public function, which is its constructor:
<pre>
template &lt;class Predicate, class BaseIterator&gt;
typename detail::filter_generator&lt;Predicate, BaseIterator&gt;::type
typename filter_generator&lt;Predicate, BaseIterator&gt;::type
make_filter_iterator(BaseIterator first, BaseIterator last, const Predicate& p = Predicate())
</pre>

View File

@ -7,7 +7,6 @@
// "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>
@ -20,17 +19,26 @@ struct is_positive_number {
int main()
{
int numbers[] = { 0, -1, 4, -3, 5, 8, -2 };
const int N = sizeof(numbers)/sizeof(int);
int numbers_[] = { 0, -1, 4, -3, 5, 8, -2 };
const int N = sizeof(numbers_)/sizeof(int);
#ifdef BOOST_NO_STD_ITERATOR_TRAITS
// Assume there won't be proper iterator traits for pointers. This
// is just a wrapper for int* which has the right traits.
typedef boost::iterator_adaptor<int*, boost::default_iterator_policies, int> base_iterator;
#else
typedef int* base_iterator;
#endif
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, " "));
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_generator
typedef boost::filter_iterator_generator<is_positive_number, int*, int>::type
typedef boost::filter_iterator_generator<is_positive_number, base_iterator, int>::type
FilterIter;
is_positive_number predicate;
FilterIter::policies_type policies(predicate, numbers + N);
@ -42,10 +50,10 @@ int main()
// Another example using make_filter_iterator()
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::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;

View File

@ -33,7 +33,7 @@ int main(int, char*[])
std::string s = "";
std::copy(x.begin(), x.end(),
boost::make_function_output_iterator(string_appender(s)));
boost::make_function_output_iterator(string_appender(s)));
std::cout << s << std::endl;

150
generator_iterator.htm Normal file
View File

@ -0,0 +1,150 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head>
<title>Generator 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>Generator Iterator Adaptor</h1>
Defined in header <a href="../../boost/generator_iterator.hpp">boost/generator_iterator.hpp</a>
<p>
The generator iterator adaptor makes it easier to create custom input
iterators from 0-ary functions and function objects. The adaptor
takes a
<a href="http://www.sgi.com/tech/stl/Generator.html">Generator</a>
and creates a model of
<a href="http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a>.
Each increment retrieves an item from the generator and makes it
available to be retrieved by dereferencing. The motivation for this
iterator is that some concepts can be more naturally expressed as a
generator, while most STL algorithms expect an iterator. An example
is the <a href="../random/index.html">Random Number</a> library.
<h2>Synopsis</h2>
<blockquote>
<pre>
namespace boost {
template &lt;class Generator&gt;
class generator_iterator_policies;
template &lt;class Generator&gt;
class generator_iterator_generator;
template &lt;class Generator&gt;
typename generator_iterator_generator&lt;Generator&gt;::type
make_generator_iterator(Generator &amp; gen);
}
</pre>
</blockquote>
<hr>
<h2>The Generator Iterator Generator Class</h2>
The class generator_iterator_generator is a helper class whose purpose
is to construct a generator iterator type. The template parameter for
this class is the Generator function object type that is being
wrapped. The generator iterator adaptor only holds a reference (or
pointer) to the function object, therefore the function object must
outlive the generator iterator adaptor constructed from it.
<pre>
template &lt;class Generator>
class generator_iterator_generator
{
public:
typedef <a href="iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a>&lt...&gt; type; // the resulting generator iterator type
}
</pre>
<h3>Template Parameters</h3>
<table border>
<tr>
<th>Parameter</th>
<th>Description</th>
</tr>
<tr>
<td><tt><a href="http://www.sgi.com/tech/stl/Generator.html">Generator</a></tt>
<td>The generator (0-ary function object) type being
wrapped. The return type of the function must be defined as
<tt>Generator::result_type</tt>. The function object must be a model
of
<a href="http://www.sgi.com/tech/stl/Generator.html">Generator</a>.
</td>
</table>
<h3>Concept Model</h3>
The generator iterator class is a model of
<a href="http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a>.
<h3>Members</h3>
The generator iterator implements the member functions
and operators required of the
<a href="http://www.sgi.com/tech/stl/InputIterator.html">Input Iterator</a>
concept.
<br>
<hr>
<h2><a name="make_generator_iterator">The Generator Iterator Object Generator</a></h2>
The <tt>make_generator_iterator()</tt> function provides a
convenient way to create generator iterator objects. The function
saves the user the trouble of explicitly writing out the iterator
types.
<blockquote>
<pre>
template &lt;class Generator&gt;
typename generator_iterator_generator&lt;Generator&gt;::type
make_function_output_iterator(Generator &amp; gen);
</pre>
</blockquote>
<hr>
<h3>Example</h3>
The following program shows how <code>generator_iterator</code>
transforms a generator into an input iterator.
<blockquote>
<pre>
#include &lt;iostream>
#include &lt;boost/generator_iterator.hpp>
class my_generator
{
public:
typedef int result_type;
my_generator() : state(0) { }
int operator()() { return ++state; }
private:
int state;
};
int main()
{
my_generator gen;
boost::generator_iterator_generator&lt;my_generator&gt;::type it = boost::make_generator_iterator(gen);
for(int i = 0; i &lt; 10; ++i, ++it)
std::cout &lt;&lt; *it &lt;&lt; std::endl;
}
</pre>
</blockquote>
<hr>
Written by Jens Maurer.
</body>
</html>

View File

@ -346,7 +346,7 @@ int main()
test_integer<unsigned int>();
test_integer<long>();
test_integer<unsigned long>();
#if defined(ULLONG_MAX) || defined(ULONG_LONG_MAX)
#if defined(BOOST_HAS_LONG_LONG)
test_integer<long long>();
test_integer<unsigned long long>();
#endif

52
include/boost/assert.hpp Normal file
View File

@ -0,0 +1,52 @@
#ifndef BOOST_ASSERT_HPP_INCLUDED
#define BOOST_ASSERT_HPP_INCLUDED
#if _MSC_VER >= 1020
#pragma once
#endif
//
// boost/assert.hpp
//
// 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.
//
//
// When BOOST_DEBUG is not defined, it defaults to 0 (off)
// for compatibility with programs that do not expect asserts
// in the smart pointer class templates.
//
// This default may be changed after an initial transition period.
//
#ifndef BOOST_DEBUG
#define BOOST_DEBUG 0
#endif
#if BOOST_DEBUG
#include <assert.h>
#ifndef BOOST_ASSERT
#include <boost/current_function.hpp>
bool boost_error(char const * expr, char const * func, char const * file, long line);
# define BOOST_ASSERT(expr) ((expr) || !boost_error(#expr, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__) || (assert(expr), true))
#endif // #ifndef BOOST_ASSERT
#else // #if BOOST_DEBUG
#undef BOOST_ASSERT
#define BOOST_ASSERT(expr) ((void)0)
#endif // #if BOOST_DEBUG
#endif // #ifndef BOOST_ASSERT_HPP_INCLUDED

View File

@ -0,0 +1,60 @@
#ifndef BOOST_CHECKED_DELETE_HPP_INCLUDED
#define BOOST_CHECKED_DELETE_HPP_INCLUDED
#if _MSC_VER >= 1020
#pragma once
#endif
//
// boost/checked_delete.hpp
//
// Copyright (c) 1999, 2000, 2001, 2002 boost.org
//
// 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.
//
namespace boost
{
// verify that types are complete for increased safety
template< typename T > inline void checked_delete(T * x)
{
typedef char type_must_be_complete[sizeof(T)];
delete x;
}
template< typename T > inline void checked_array_delete(T * x)
{
typedef char type_must_be_complete[sizeof(T)];
delete [] x;
}
template<class T> struct checked_deleter
{
typedef void result_type;
typedef T * argument_type;
void operator()(T * x)
{
checked_delete(x);
}
};
template<class T> struct checked_array_deleter
{
typedef void result_type;
typedef T * argument_type;
void operator()(T * x)
{
checked_array_delete(x);
}
};
} // namespace boost
#endif // #ifndef BOOST_CHECKED_DELETE_HPP_INCLUDED

View File

@ -0,0 +1,56 @@
#ifndef BOOST_CURRENT_FUNCTION_HPP_INCLUDED
#define BOOST_CURRENT_FUNCTION_HPP_INCLUDED
#if _MSC_VER >= 1020
#pragma once
#endif
//
// boost/current_function.hpp - BOOST_CURRENT_FUNCTION
//
// 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.
//
namespace boost
{
namespace detail
{
inline void current_function_helper()
{
#if defined(__GNUC__)
# define BOOST_CURRENT_FUNCTION __PRETTY_FUNCTION__
#elif defined(__FUNCSIG__)
# define BOOST_CURRENT_FUNCTION __FUNCSIG__
#elif defined(__BORLANDC__)
# define BOOST_CURRENT_FUNCTION __FUNC__
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901)
# define BOOST_CURRENT_FUNCTION __func__
#else
# define BOOST_CURRENT_FUNCTION "(unknown)"
#endif
}
} // namespace detail
} // namespace boost
#endif // #ifndef BOOST_CURRENT_FUNCTION_HPP_INCLUDED

View File

@ -34,20 +34,32 @@ namespace boost{
namespace detail{
template <typename T, bool isp, bool b1, bool b2>
template <typename T, bool small_>
struct ct_imp2
{
typedef const T& param_type;
};
template <typename T>
struct ct_imp2<T, true>
{
typedef const T param_type;
};
template <typename T, bool isp, bool b1>
struct ct_imp
{
typedef const T& param_type;
};
template <typename T, bool isp>
struct ct_imp<T, isp, true, true>
struct ct_imp<T, isp, true>
{
typedef T const param_type;
typedef typename ct_imp2<T, sizeof(T) <= sizeof(void*)>::param_type param_type;
};
template <typename T, bool b1, bool b2>
struct ct_imp<T, true, b1, b2>
template <typename T, bool b1>
struct ct_imp<T, true, b1>
{
typedef T const param_type;
};
@ -67,7 +79,11 @@ public:
// however compiler bugs prevent this - instead pass three bool's to
// ct_imp<T,bool,bool,bool> and add an extra partial specialisation
// of ct_imp to handle the logic. (JM)
typedef typename detail::ct_imp<T, ::boost::is_pointer<typename remove_const<T>::type>::value, ::boost::is_arithmetic<typename remove_const<T>::type>::value, sizeof(T) <= sizeof(void*)>::param_type param_type;
typedef typename detail::ct_imp<
T,
::boost::is_pointer<T>::value,
::boost::is_arithmetic<T>::value
>::param_type param_type;
};
template <typename T>
@ -79,7 +95,7 @@ struct call_traits<T&>
typedef T& param_type; // hh removed const
};
#if defined(__BORLANDC__) && (__BORLANDC__ <= 0x551)
#if defined(__BORLANDC__) && (__BORLANDC__ <= 0x560)
// 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

View File

@ -33,7 +33,7 @@
namespace boost{
#if defined(BOOST_MSVC6_MEMBER_TEMPLATES) || !defined(BOOST_NO_MEMBER_TEMPLATES)
#ifdef BOOST_MSVC6_MEMBER_TEMPLATES
//
// use member templates to emulate
// partial specialisation:
@ -64,7 +64,8 @@ struct reference_call_traits
typedef T const_reference;
typedef T param_type;
};
template <bool simple, bool reference>
template <bool pointer, bool arithmetic, bool reference>
struct call_traits_chooser
{
template <class T>
@ -73,8 +74,9 @@ struct call_traits_chooser
typedef standard_call_traits<T> type;
};
};
template <>
struct call_traits_chooser<true, false>
struct call_traits_chooser<true, false, false>
{
template <class T>
struct rebind
@ -82,8 +84,9 @@ struct call_traits_chooser<true, false>
typedef simple_call_traits<T> type;
};
};
template <>
struct call_traits_chooser<false, true>
struct call_traits_chooser<false, false, true>
{
template <class T>
struct rebind
@ -91,12 +94,50 @@ struct call_traits_chooser<false, true>
typedef reference_call_traits<T> type;
};
};
template <bool size_is_small>
struct call_traits_sizeof_chooser2
{
template <class T>
struct small_rebind
{
typedef simple_call_traits<T> small_type;
};
};
template<>
struct call_traits_sizeof_chooser2<false>
{
template <class T>
struct small_rebind
{
typedef standard_call_traits<T> small_type;
};
};
template <>
struct call_traits_chooser<false, true, false>
{
template <class T>
struct rebind
{
enum { sizeof_choice = (sizeof(T) <= sizeof(void*)) };
typedef call_traits_sizeof_chooser2<(sizeof(T) <= sizeof(void*))> chooser;
typedef typename chooser::template small_rebind<T> bound_type;
typedef typename bound_type::small_type type;
};
};
} // namespace detail
template <typename T>
struct call_traits
{
private:
typedef detail::call_traits_chooser<(is_pointer<T>::value || is_arithmetic<T>::value) && sizeof(T) <= sizeof(void*), is_reference<T>::value> chooser;
typedef detail::call_traits_chooser<
::boost::is_pointer<T>::value,
::boost::is_arithmetic<T>::value,
::boost::is_reference<T>::value
> chooser;
typedef typename chooser::template rebind<T> bound_type;
typedef typename bound_type::type call_traits_type;
public:

View File

@ -10,8 +10,8 @@
/* Release notes:
20 Jan 2001:
Fixed obvious bugs (David Abrahams)
07 Oct 2000:
Added better single argument constructor support.
07 Oct 2000:
Added better single argument constructor support.
03 Oct 2000:
Added VC6 support (JM).
23rd July 2000:
@ -38,7 +38,7 @@
namespace boost
{
#if defined(BOOST_MSVC6_MEMBER_TEMPLATES) || !defined(BOOST_NO_MEMBER_TEMPLATES)
#ifdef BOOST_MSVC6_MEMBER_TEMPLATES
//
// use member templates to emulate
// partial specialisation. Note that due to
@ -168,7 +168,7 @@ public:
compressed_pair_1(const ::boost::compressed_pair<T1,T2>& x)
: T2(x.second()), _first(x.first()) {}
#ifdef BOOST_MSVC
#if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
// Total weirdness. If the assignment to _first is moved after
// the call to the inherited operator=, then this breaks graph/test/graph.cpp
// by way of iterator_adaptor.

View File

@ -0,0 +1,73 @@
// (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.
//
// Revision History:
// 15 Nov 2001 Jens Maurer
// created.
#ifndef BOOST_ITERATOR_ADAPTOR_GENERATOR_ITERATOR_HPP
#define BOOST_ITERATOR_ADAPTOR_GENERATOR_ITERATOR_HPP
#include <boost/iterator_adaptors.hpp>
#include <boost/ref.hpp>
namespace boost {
template<class Generator>
class generator_iterator_policies
{
public:
generator_iterator_policies() { }
template<class Base>
void initialize(Base& base) {
m_value = (*base)();
}
// The Iter template argument is necessary for compatibility with a MWCW
// bug workaround
template <class IteratorAdaptor>
void increment(IteratorAdaptor& iter) {
m_value = (*iter.base())();
}
template <class IteratorAdaptor>
const typename Generator::result_type&
dereference(const IteratorAdaptor&) const
{ return m_value; }
template <class IteratorAdaptor1, class IteratorAdaptor2>
bool equal(const IteratorAdaptor1& x, const IteratorAdaptor2& y) const
{ return x.base() == y.base() &&
x.policies().m_value == y.policies().m_value; }
private:
typename Generator::result_type m_value;
};
template<class Generator>
struct generator_iterator_generator
{
typedef iterator_adaptor<Generator*, generator_iterator_policies<Generator>,
typename Generator::result_type, const typename Generator::result_type&,
const typename Generator::result_type*, std::input_iterator_tag,
long> type;
};
template <class Generator>
inline typename generator_iterator_generator<Generator>::type
make_generator_iterator(Generator & gen)
{
typedef typename generator_iterator_generator<Generator>::type result_t;
return result_t(&gen);
}
} // namespace boost
#endif // BOOST_ITERATOR_ADAPTOR_GENERATOR_ITERATOR_HPP

View File

@ -9,6 +9,12 @@
// See http://www.boost.org for most recent version including documentation.
// Revision History
// 02 Dec 01 Bug fixed in random_access_iteratable. (Helmut Zeisel)
// 28 Sep 01 Factored out iterator operator groups. (Daryle Walker)
// 27 Aug 01 'left' form for non commutative operators added;
// additional classes for groups of related operators added;
// workaround for empty base class optimization
// bug of GCC 3.0 (Helmut Zeisel)
// 25 Jun 01 output_iterator_helper changes: removed default template
// parameters, added support for self-proxying, additional
// documentation and tests (Aleksey Gurtovoy)
@ -81,7 +87,14 @@
namespace boost {
namespace detail {
// Helmut Zeisel, empty base class optimization bug with GCC 3.0.0
#if defined(__GNUC__) && __GNUC__==3 && __GNUC_MINOR__==0 && __GNU_PATCHLEVEL__==0
class empty_base {
bool dummy;
};
#else
class empty_base {};
#endif
} // namespace detail
} // namespace boost
@ -168,6 +181,13 @@ struct subtractable2 : B
friend T operator-(T x, const U& y) { return x -= y; }
};
template <class T, class U, class B = ::boost::detail::empty_base>
struct subtractable2_left : B
{
friend T operator-(const U& x, const T& y)
{ T result(x); return result -= y; }
};
template <class T, class B = ::boost::detail::empty_base>
struct subtractable1 : B
{
@ -180,6 +200,13 @@ struct dividable2 : B
friend T operator/(T x, const U& y) { return x /= y; }
};
template <class T, class U, class B = ::boost::detail::empty_base>
struct dividable2_left : B
{
friend T operator/(const U& x, const T& y)
{ T result(x); return result /= y; }
};
template <class T, class B = ::boost::detail::empty_base>
struct dividable1 : B
{
@ -192,6 +219,13 @@ struct modable2 : B
friend T operator%(T x, const U& y) { return x %= y; }
};
template <class T, class U, class B = ::boost::detail::empty_base>
struct modable2_left : B
{
friend T operator%(const U& x, const T& y)
{ T result(x); return result %= y; }
};
template <class T, class B = ::boost::detail::empty_base>
struct modable1 : B
{
@ -463,12 +497,125 @@ struct shiftable1
, right_shiftable1<T, B
> > {};
template <class T, class U, class B = ::boost::detail::empty_base>
struct ring_operators2
: additive2<T, U
, subtractable2_left<T, U
, multipliable2<T, U, B
> > > {};
template <class T, class B = ::boost::detail::empty_base>
struct ring_operators1
: additive1<T
, multipliable1<T, B
> > {};
template <class T, class U, class B = ::boost::detail::empty_base>
struct ordered_ring_operators2
: ring_operators2<T, U
, totally_ordered2<T, U, B
> > {};
template <class T, class B = ::boost::detail::empty_base>
struct ordered_ring_operators1
: ring_operators1<T
, totally_ordered1<T, B
> > {};
template <class T, class U, class B = ::boost::detail::empty_base>
struct field_operators2
: ring_operators2<T, U
, dividable2<T, U
, dividable2_left<T, U, B
> > > {};
template <class T, class B = ::boost::detail::empty_base>
struct field_operators1
: ring_operators1<T
, dividable1<T, B
> > {};
template <class T, class U, class B = ::boost::detail::empty_base>
struct ordered_field_operators2
: field_operators2<T, U
, totally_ordered2<T, U, B
> > {};
template <class T, class B = ::boost::detail::empty_base>
struct ordered_field_operators1
: field_operators1<T
, totally_ordered1<T, B
> > {};
template <class T, class U, class B = ::boost::detail::empty_base>
struct euclidian_ring_operators2
: ring_operators2<T, U
, dividable2<T, U
, dividable2_left<T, U
, modable2<T, U
, modable2_left<T, U, B
> > > > > {};
template <class T, class B = ::boost::detail::empty_base>
struct euclidian_ring_operators1
: ring_operators1<T
, dividable1<T
, modable1<T, B
> > > {};
template <class T, class U, class B = ::boost::detail::empty_base>
struct ordered_euclidian_ring_operators2
: totally_ordered2<T, U
, euclidian_ring_operators2<T, U, B
> > {};
template <class T, class B = ::boost::detail::empty_base>
struct ordered_euclidian_ring_operators1
: totally_ordered1<T
, euclidian_ring_operators1<T, B
> > {};
template <class T, class P, class B = ::boost::detail::empty_base>
struct input_iteratable
: equality_comparable1<T
, incrementable<T
, dereferenceable<T, P, B
> > > {};
template <class T, class B = ::boost::detail::empty_base>
struct output_iteratable
: incrementable<T, B
> {};
template <class T, class P, class B = ::boost::detail::empty_base>
struct forward_iteratable
: input_iteratable<T, P, B
> {};
template <class T, class P, class B = ::boost::detail::empty_base>
struct bidirectional_iteratable
: forward_iteratable<T, P
, decrementable<T, B
> > {};
// To avoid repeated derivation from equality_comparable,
// which is an indirect base class of bidirectional_iterable,
// random_access_iteratable must not be derived from totally_ordered1
// but from less_than_comparable1 only. (Helmut Zeisel, 02-Dec-2001)
template <class T, class P, class D, class R, class B = ::boost::detail::empty_base>
struct random_access_iteratable
: bidirectional_iteratable<T, P
, less_than_comparable1<T
, additive2<T, D
, indexable<T, D, R, B
> > > > {};
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
} // namespace boost
#endif // BOOST_NO_OPERATORS_IN_NAMESPACE
// BOOST_IMPORT_TEMPLATE1 .. BOOST_IMPORT_TEMPLATE3 -
// BOOST_IMPORT_TEMPLATE1 .. BOOST_IMPORT_TEMPLATE4 -
//
// When BOOST_NO_OPERATORS_IN_NAMESPACE is defined we need a way to import an
// operator template into the boost namespace. BOOST_IMPORT_TEMPLATE1 is used
@ -479,6 +626,7 @@ struct shiftable1
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
// The template is already in boost so we have nothing to do.
# define BOOST_IMPORT_TEMPLATE4(template_name)
# define BOOST_IMPORT_TEMPLATE3(template_name)
# define BOOST_IMPORT_TEMPLATE2(template_name)
# define BOOST_IMPORT_TEMPLATE1(template_name)
@ -489,6 +637,7 @@ struct shiftable1
// Bring the names in with a using-declaration
// to avoid stressing the compiler.
# define BOOST_IMPORT_TEMPLATE4(template_name) using ::template_name;
# define BOOST_IMPORT_TEMPLATE3(template_name) using ::template_name;
# define BOOST_IMPORT_TEMPLATE2(template_name) using ::template_name;
# define BOOST_IMPORT_TEMPLATE1(template_name) using ::template_name;
@ -497,6 +646,10 @@ struct shiftable1
// Otherwise, because a Borland C++ 5.5 bug prevents a using declaration
// from working, we are forced to use inheritance for that compiler.
# define BOOST_IMPORT_TEMPLATE4(template_name) \
template <class T, class U, class V, class W, class B = ::boost::detail::empty_base> \
struct template_name : ::template_name<T, U, V, W, B> {};
# define BOOST_IMPORT_TEMPLATE3(template_name) \
template <class T, class U, class V, class B = ::boost::detail::empty_base> \
struct template_name : ::template_name<T, U, V, B> {};
@ -542,6 +695,15 @@ template<class T> struct is_chained_base {
} // namespace boost
// Import a 4-type-argument operator template into boost (if neccessary) and
// provide a specialization of 'is_chained_base<>' for it.
# define BOOST_OPERATOR_TEMPLATE4(template_name4) \
BOOST_IMPORT_TEMPLATE4(template_name4) \
template<class T, class U, class V, class W, class B> \
struct is_chained_base< ::boost::template_name4<T, U, V, W, B> > { \
typedef ::boost::detail::true_t value; \
};
// Import a 3-type-argument operator template into boost (if neccessary) and
// provide a specialization of 'is_chained_base<>' for it.
# define BOOST_OPERATOR_TEMPLATE3(template_name3) \
@ -610,6 +772,8 @@ BOOST_OPERATOR_TEMPLATE1(template_name##1)
#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
# define BOOST_OPERATOR_TEMPLATE4(template_name4) \
BOOST_IMPORT_TEMPLATE4(template_name4)
# define BOOST_OPERATOR_TEMPLATE3(template_name3) \
BOOST_IMPORT_TEMPLATE3(template_name3)
# define BOOST_OPERATOR_TEMPLATE2(template_name2) \
@ -632,8 +796,11 @@ BOOST_OPERATOR_TEMPLATE(equality_comparable)
BOOST_OPERATOR_TEMPLATE(multipliable)
BOOST_OPERATOR_TEMPLATE(addable)
BOOST_OPERATOR_TEMPLATE(subtractable)
BOOST_OPERATOR_TEMPLATE2(subtractable2_left)
BOOST_OPERATOR_TEMPLATE(dividable)
BOOST_OPERATOR_TEMPLATE2(dividable2_left)
BOOST_OPERATOR_TEMPLATE(modable)
BOOST_OPERATOR_TEMPLATE2(modable2_left)
BOOST_OPERATOR_TEMPLATE(xorable)
BOOST_OPERATOR_TEMPLATE(andable)
BOOST_OPERATOR_TEMPLATE(orable)
@ -658,14 +825,27 @@ BOOST_OPERATOR_TEMPLATE(integer_arithmetic)
BOOST_OPERATOR_TEMPLATE(bitwise)
BOOST_OPERATOR_TEMPLATE1(unit_steppable)
BOOST_OPERATOR_TEMPLATE(shiftable)
BOOST_OPERATOR_TEMPLATE(ring_operators)
BOOST_OPERATOR_TEMPLATE(ordered_ring_operators)
BOOST_OPERATOR_TEMPLATE(field_operators)
BOOST_OPERATOR_TEMPLATE(ordered_field_operators)
BOOST_OPERATOR_TEMPLATE(euclidian_ring_operators)
BOOST_OPERATOR_TEMPLATE(ordered_euclidian_ring_operators)
BOOST_OPERATOR_TEMPLATE2(input_iteratable)
BOOST_OPERATOR_TEMPLATE1(output_iteratable)
BOOST_OPERATOR_TEMPLATE2(forward_iteratable)
BOOST_OPERATOR_TEMPLATE2(bidirectional_iteratable)
BOOST_OPERATOR_TEMPLATE4(random_access_iteratable)
#undef BOOST_OPERATOR_TEMPLATE
#undef BOOST_OPERATOR_TEMPLATE4
#undef BOOST_OPERATOR_TEMPLATE3
#undef BOOST_OPERATOR_TEMPLATE2
#undef BOOST_OPERATOR_TEMPLATE1
#undef BOOST_IMPORT_TEMPLATE1
#undef BOOST_IMPORT_TEMPLATE2
#undef BOOST_IMPORT_TEMPLATE3
#undef BOOST_IMPORT_TEMPLATE4
// The following 'operators' classes can only be used portably if the derived class
// declares ALL of the required member operators.
@ -699,20 +879,18 @@ template <class T,
class P = V const *,
class R = V const &>
struct input_iterator_helper
: equality_comparable1<T
, incrementable<T
, dereferenceable<T, P
: input_iteratable<T, P
, boost::iterator<std::input_iterator_tag, V, D, P, R
> > > > {};
> > {};
template<class Derived>
template<class T>
struct output_iterator_helper
: boost::incrementable<Derived
: output_iteratable<T
, boost::iterator<std::output_iterator_tag, void, void, void, void
> >
{
Derived& operator*() { return static_cast<Derived&>(*this); }
Derived& operator++() { return static_cast<Derived&>(*this); }
T& operator*() { return static_cast<T&>(*this); }
T& operator++() { return static_cast<T&>(*this); }
};
template <class T,
@ -721,11 +899,9 @@ template <class T,
class P = V*,
class R = V&>
struct forward_iterator_helper
: equality_comparable1<T
, incrementable<T
, dereferenceable<T, P
: forward_iteratable<T, P
, boost::iterator<std::forward_iterator_tag, V, D, P, R
> > > > {};
> > {};
template <class T,
class V,
@ -733,11 +909,9 @@ template <class T,
class P = V*,
class R = V&>
struct bidirectional_iterator_helper
: equality_comparable1<T
, unit_steppable<T
, dereferenceable<T, P
: bidirectional_iteratable<T, P
, boost::iterator<std::bidirectional_iterator_tag, V, D, P, R
> > > > {};
> > {};
template <class T,
class V,
@ -745,13 +919,9 @@ template <class T,
class P = V*,
class R = V&>
struct random_access_iterator_helper
: totally_ordered1<T
, unit_steppable<T
, dereferenceable<T, P
, additive2<T, D
, indexable<T, D, R
: random_access_iteratable<T, P, D, R
, boost::iterator<std::random_access_iterator_tag, V, D, P, R
> > > > > >
> >
{
friend D requires_difference_operator(const T& x, const T& y) {
return x - y;

View File

@ -1,16 +1,19 @@
#ifndef BOOST_REF_HPP_INCLUDED
#define BOOST_REF_HPP_INCLUDED
# define BOOST_REF_HPP_INCLUDED
#if _MSC_VER >= 1020
#pragma once
#endif
# if _MSC_VER+0 >= 1020
# pragma once
# endif
# include <boost/config.hpp>
# include <boost/utility/addressof.hpp>
//
// ref.hpp - ref/cref, useful helper functions
//
// Version 1.00.0003 (2001-08-22)
//
// Copyright (C) 1999, 2000 Jaakko J<>rvi (jaakko.jarvi@cs.utu.fi)
// 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.
@ -26,30 +29,134 @@ namespace boost
template<class T> class reference_wrapper
{
public:
typedef T type;
explicit reference_wrapper(T & t): t_(t) {}
#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300)
operator T & () const { return t_; }
explicit reference_wrapper(T& t): t_(&t) {}
T & get() const { return t_; }
#else
explicit reference_wrapper(T& t): t_(addressof(t)) {}
#endif
operator T& () const { return *t_; }
T& get() const { return *t_; }
T* get_pointer() const { return t_; }
private:
T & t_;
reference_wrapper & operator= (reference_wrapper const &);
T* t_;
};
template<class T> inline reference_wrapper<T> ref(T & t)
# if defined(__BORLANDC__) && (__BORLANDC__ <= 0x560)
# define BOOST_REF_CONST
# else
# define BOOST_REF_CONST const
# endif
template<class T> inline reference_wrapper<T> BOOST_REF_CONST ref(T & t)
{
return reference_wrapper<T>(t);
}
template<class T> inline reference_wrapper<T const> cref(T const & t)
template<class T> inline reference_wrapper<T const> BOOST_REF_CONST cref(T const & t)
{
return reference_wrapper<T const>(t);
}
# undef BOOST_REF_CONST
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template<typename T>
class is_reference_wrapper
{
public:
BOOST_STATIC_CONSTANT(bool, value = false);
};
template<typename T>
class is_reference_wrapper<reference_wrapper<T> >
{
public:
BOOST_STATIC_CONSTANT(bool, value = true);
};
template<typename T>
class unwrap_reference
{
public:
typedef T type;
};
template<typename T>
class unwrap_reference<reference_wrapper<T> >
{
public:
typedef T type;
};
# else // no partial specialization
} // namespace boost
#include <boost/type.hpp>
namespace boost
{
namespace detail
{
typedef char (&yes_reference_wrapper_t)[1];
typedef char (&no_reference_wrapper_t)[2];
no_reference_wrapper_t is_reference_wrapper_test(...);
template<typename T>
yes_reference_wrapper_t is_reference_wrapper_test(type< reference_wrapper<T> >);
template<bool wrapped>
struct reference_unwrapper
{
template <class T>
struct apply
{
typedef T type;
};
};
template<>
struct reference_unwrapper<true>
{
template <class T>
struct apply
{
typedef typename T::type type;
};
};
}
template<typename T>
class is_reference_wrapper
{
public:
BOOST_STATIC_CONSTANT(
bool, value = (
sizeof(detail::is_reference_wrapper_test(type<T>()))
== sizeof(detail::yes_reference_wrapper_t)));
};
template <typename T>
class unwrap_reference
: public detail::reference_unwrapper<
is_reference_wrapper<T>::value
>::template apply<T>
{};
# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
} // namespace boost
#endif // #ifndef BOOST_REF_HPP_INCLUDED

View File

@ -13,37 +13,14 @@
#ifndef BOOST_UTILITY_HPP
#define BOOST_UTILITY_HPP
#include <boost/config.hpp> // broken compiler workarounds
#include <boost/static_assert.hpp>
// certain headers are part of the <utility.hpp> interface
#include <boost/checked_delete.hpp>
#include <boost/utility/base_from_member.hpp>
#include <cstddef> // for size_t
#include <utility> // for std::pair
#include <boost/utility/addressof.hpp>
namespace boost
{
// checked_delete() and checked_array_delete() -----------------------------//
// verify that types are complete for increased safety
template< typename T >
inline void checked_delete(T * x)
{
BOOST_STATIC_ASSERT( sizeof(T) != 0 ); // assert type complete at point
// of instantiation
delete x;
}
template< typename T >
inline void checked_array_delete(T * x)
{
BOOST_STATIC_ASSERT( sizeof(T) != 0 ); // assert type complete at point
// of instantiation
delete [] x;
}
// next() and prior() template functions -----------------------------------//
// Helper functions for classes like bidirectional iterators not supporting

View File

@ -0,0 +1,31 @@
// Copyright (C) 2002 Brad King (brad.king@kitware.com)
// Doug 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.
// For more information, see http://www.boost.org
#ifndef BOOST_UTILITY_ADDRESSOF_HPP
#define BOOST_UTILITY_ADDRESSOF_HPP
namespace boost {
// Do not make addressof() inline. Breaks MSVC 7. (Peter Dimov)
template <typename T> T* addressof(T& v)
{
return reinterpret_cast<T*>(
&const_cast<char&>(reinterpret_cast<const volatile char &>(v)));
}
}
#endif // BOOST_UTILITY_ADDRESSOF_HPP

34
index.html Normal file
View File

@ -0,0 +1,34 @@
<html>
<head>
<meta http-equiv="Content-Language" content="en-us">
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>Boost Utility Library</title>
</head>
<body bgcolor="#FFFFFF">
<h1><IMG SRC="../../c++boost.gif" WIDTH="276" HEIGHT="86" align="center">Boost
Utility Library</h1>
<p>The Boost Utility Library isn't really a single library at all.&nbsp; It is
just a collection for components too small to be called libraries in their own
right.</p>
<p>But that doesn't mean there isn't useful stuff here.&nbsp; Take a look:</p>
<blockquote>
<p><a href="base_from_member.html">base_from_member</a><br>
<a href="call_traits.htm">call_traits.htm</a><br>
<a href="compressed_pair.htm">compressed_pair.htm</a><br>
<a href="operators.htm">operators.htm</a><br>
<a href="tie.html">tie</a><br>
<a href="utility.htm">utility.htm</a></p>
</blockquote>
<hr>
<p>Revised
<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan -->07 May, 2002<!--webbot bot="Timestamp" endspan i-checksum="13976" --></p>
<p>&nbsp;</p>
</body>
</html>

View File

@ -42,19 +42,19 @@ int main(int, char*[])
const_indirect_last(pointers_to_chars + N);
std::transform(const_indirect_first, const_indirect_last,
mutable_indirect_first, std::bind1st(std::plus<char>(), 1));
mutable_indirect_first, std::bind1st(std::plus<char>(), 1));
std::copy(mutable_indirect_first, mutable_indirect_last,
std::ostream_iterator<char>(std::cout, ","));
std::ostream_iterator<char>(std::cout, ","));
std::cout << std::endl;
// Example of using make_indirect_iterator()
#ifndef BOOST_MSVC
#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
std::copy(boost::make_indirect_iterator(pointers_to_chars),
boost::make_indirect_iterator(pointers_to_chars + N),
std::ostream_iterator<char>(std::cout, ","));
boost::make_indirect_iterator(pointers_to_chars + N),
std::ostream_iterator<char>(std::cout, ","));
std::cout << std::endl;
#endif

View File

@ -31,7 +31,7 @@ typedef std::set<storage::iterator> iterator_set;
void more_indirect_iterator_tests()
{
// For some reason all heck breaks loose in the compiler under these conditions.
#if !defined(BOOST_MSVC) || !defined(__STL_DEBUG)
#if !defined(BOOST_MSVC) || BOOST_MSVC > 1200 || !defined(__STL_DEBUG)
storage store(1000);
std::generate(store.begin(), store.end(), rand);
@ -46,7 +46,7 @@ void more_indirect_iterator_tests()
typedef boost::indirect_iterator_pair_generator<
pointer_deque::iterator
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#ifdef BOOST_NO_STD_ITERATOR_TRAITS
, int
#endif
> IndirectDeque;
@ -75,7 +75,7 @@ void more_indirect_iterator_tests()
typedef boost::indirect_iterator_generator<
iterator_set::iterator
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#ifdef BOOST_NO_STD_ITERATOR_TRAITS
, int
#endif
>::type indirect_set_iterator;
@ -117,7 +117,7 @@ main()
ptr[k] = array + k;
typedef boost::indirect_iterator_generator<dummyT**
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#ifdef BOOST_NO_STD_ITERATOR_TRAITS
, dummyT
#endif
>::type indirect_iterator;
@ -127,7 +127,7 @@ main()
indirect_iterator i(ptr);
boost::random_access_iterator_test(i, N, array);
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#ifndef BOOST_NO_STD_ITERATOR_TRAITS
boost::random_access_iterator_test(boost::make_indirect_iterator(ptr), N, array);
#endif
@ -139,7 +139,7 @@ main()
dummyT*const* const_ptr = ptr;
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#ifndef BOOST_NO_STD_ITERATOR_TRAITS
boost::random_access_iterator_test(boost::make_indirect_iterator(const_ptr), N, array);
#endif
boost::const_nonconst_iterator_test(i, ++j);

View File

@ -21,7 +21,7 @@ main()
{
using boost::dummyT;
dummyT array[] = { dummyT(0), dummyT(1), dummyT(2),
dummyT(3), dummyT(4), dummyT(5) };
dummyT(3), dummyT(4), dummyT(5) };
typedef boost::iterator_adaptor<dummyT*,
boost::default_iterator_policies, dummyT> my_iter;
my_iter mi(array);

View File

@ -9,6 +9,8 @@
// See http://www.boost.org for most recent version including documentation.
// Revision History
// 30 Nov 01 Added permutation_iterator.(Toon Knapen)
// 19 Nov 01 Added generator_iterator. (Jens Maurer)
// 04 Nov 01 Updated with respect to change in named parameters.
// (Jeremy Siek)
// 08 Mar 01 Moved indirect and transform tests to separate files.
@ -49,12 +51,15 @@
#include <algorithm>
#include <functional>
#include <numeric>
#include <boost/iterator_adaptors.hpp>
#include <boost/generator_iterator.hpp>
#include <boost/pending/iterator_tests.hpp>
#include <boost/pending/integer_range.hpp>
#include <boost/concept_archetype.hpp>
#include <boost/type_traits/same_traits.hpp>
#include <boost/permutation_iterator.hpp>
#include <stdlib.h>
#include <vector>
#include <deque>
@ -105,6 +110,14 @@ template <class T> struct foo;
void blah(int) { }
struct my_gen
{
typedef int result_type;
my_gen() : n(0) { }
int operator()() { return ++n; }
int n;
};
int
main()
{
@ -120,7 +133,7 @@ main()
boost::function_requires<
boost::RandomAccessIteratorPoliciesConcept<
boost::default_iterator_policies,
boost::iterator_adaptor<int*, boost::default_iterator_policies>,
boost::iterator_adaptor<storage::iterator, boost::default_iterator_policies>,
boost::iterator<std::random_access_iterator_tag, int, std::ptrdiff_t,
int*, int&>
> >();
@ -143,7 +156,7 @@ main()
boost::default_iterator_policies,
boost::value_type_is<const int> > Iter1;
BOOST_STATIC_ASSERT((boost::is_same<Iter1::value_type, int>::value));
#if defined(__BORLANDC__) || defined(BOOST_MSVC)
#if defined(__BORLANDC__) || defined(BOOST_MSVC) && BOOST_MSVC <= 1300
// We currently don't know how to workaround this bug.
BOOST_STATIC_ASSERT((boost::is_same<Iter1::reference, int&>::value));
BOOST_STATIC_ASSERT((boost::is_same<Iter1::pointer, int*>::value));
@ -211,7 +224,7 @@ main()
std::reverse(reversed, reversed + N);
typedef boost::reverse_iterator_generator<dummyT*
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) || defined(BOOST_NO_STD_ITERATOR_TRAITS)
, dummyT
#endif
>::type reverse_iterator;
@ -219,12 +232,12 @@ main()
reverse_iterator i(reversed + N);
boost::random_access_iterator_test(i, N, array);
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
boost::random_access_iterator_test(boost::make_reverse_iterator(reversed + N), N, array);
#endif
typedef boost::reverse_iterator_generator<const dummyT*
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) || defined(BOOST_NO_STD_ITERATOR_TRAITS)
, dummyT, const dummyT&, const dummyT
#endif
>::type const_reverse_iterator;
@ -234,7 +247,7 @@ main()
const dummyT* const_reversed = reversed;
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
boost::random_access_iterator_test(boost::make_reverse_iterator(const_reversed + N), N, array);
#endif
@ -269,7 +282,7 @@ main()
// Many compilers' builtin deque iterators don't interoperate well, though
// STLport fixes that problem.
#if defined(__SGI_STL_PORT) || !defined(__GNUC__) && !defined(__BORLANDC__) && !defined(BOOST_MSVC)
#if defined(__SGI_STL_PORT) || !defined(__GNUC__) && !defined(__BORLANDC__) && (!defined(BOOST_MSVC) || BOOST_MSVC > 1200)
boost::const_nonconst_iterator_test(i, ++j);
#endif
}
@ -287,7 +300,7 @@ main()
typedef boost::detail::non_bidirectional_category<dummyT*>::type category;
typedef boost::filter_iterator_generator<one_or_four, dummyT*
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) || defined(BOOST_NO_STD_ITERATOR_TRAITS)
, dummyT
#endif
>::type filter_iter;
@ -296,8 +309,8 @@ main()
// Borland is choking on accessing the policies_type explicitly
// from the filter_iter.
boost::forward_iterator_test(make_filter_iterator(array, array+N,
one_or_four()),
dummyT(1), dummyT(4));
one_or_four()),
dummyT(1), dummyT(4));
#else
filter_iter i(array, filter_iter::policies_type(one_or_four(), array + N));
boost::forward_iterator_test(i, dummyT(1), dummyT(4));
@ -314,7 +327,7 @@ main()
// On compilers not supporting partial specialization, we can do more type
// deduction with deque iterators than with pointers... unless the library
// is broken ;-(
#if !defined(BOOST_MSVC) || defined(__SGI_STL_PORT)
#if !defined(BOOST_MSVC) || BOOST_MSVC > 1200 || defined(__SGI_STL_PORT)
std::deque<dummyT> array2;
std::copy(array+0, array+N, std::back_inserter(array2));
boost::forward_iterator_test(
@ -326,7 +339,7 @@ main()
dummyT(1), dummyT(4));
#endif
#if !defined(BOOST_MSVC) // This just freaks MSVC out completely
#if !defined(BOOST_MSVC) || BOOST_MSVC > 1200 // This just freaks MSVC out completely
boost::forward_iterator_test(
boost::make_filter_iterator<one_or_four>(
boost::make_reverse_iterator(array2.end()),
@ -335,7 +348,7 @@ main()
dummyT(4), dummyT(1));
#endif
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
boost::forward_iterator_test(
boost::make_filter_iterator(array+0, array+N, one_or_four()),
dummyT(1), dummyT(4));
@ -382,6 +395,55 @@ main()
if (zero) // don't do this, just make sure it compiles
assert((*i).m_x == i->foo());
}
{
// check generator_iterator
my_gen g1;
boost::generator_iterator_generator<my_gen>::type gen =
boost::make_generator_iterator(g1);
assert(*gen == 1);
++gen;
gen++;
assert(*gen == 3);
}
{
// check permutation_iterator
typedef std::deque< 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 boost::permutation_iterator_generator< element_range_type::iterator, index_type::iterator >::type permutation_type;
permutation_type begin = boost::make_permutation_iterator( elements.begin(), indices.begin() );
permutation_type end = boost::make_permutation_iterator( elements.begin(), indices.end() );
int expected_outcome[] = { 9, 8, 7, 6 };
assert( std::equal( begin, end, expected_outcome ) );
}
std::cout << "test successful " << std::endl;
return 0;
}

View File

@ -92,6 +92,8 @@
<li><a href="#declaration_synopsis">Declaration Synopsis</a>
<li><a href="#portability">Portability</a>
<li><a href="#notes">Notes</a>
</ul>
@ -122,6 +124,10 @@
"../../boost/function_output_iterator.hpp">boost/function_output_iterator.hpp</a></tt><br>
<a href="function_output_iterator.htm">Function Output Iterator Adaptor</a>
<li>Header <tt><a href="../../boost/generator_iterator.hpp">boost/generator_iterator.hpp</a></tt><br>
<a href="generator_iterator.htm">Generator Iterator Adaptor</a>
<li>Header <tt><a href="../../boost/permutation_iterator.hpp">boost/permutation_iterator.hpp</a></tt><br>
<a href="permutation_iterator.htm">Permutation Iterator Adaptor</a>
</ul>
<p><b><a href="../../people/dave_abrahams.htm">Dave
@ -145,7 +151,11 @@
"filter_iterator.htm">filter_</a></tt> iterator generators and made some
simplifications to the main <tt><a href=
"#iterator_adaptor">iterator_adaptor</a></tt> template.<br>
<b><a href="../../people/jens_maurer.htm">Jens Maurer</a></b>
contributed the <a href="generator_iterator.htm">generator iterator</a>
adaptor.<br>
Toon Knapen contributed the <a href="permutation_iterator.htm">permutation
iterator</a> adaptor.<br>
<h2><a name="iterator_adaptor">Class template</a>
<tt>iterator_adaptor</tt></h2>
@ -174,7 +184,7 @@ struct iterator_adaptor;
<p>Although <tt>iterator_adaptor</tt> takes seven template parameters,
defaults have been carefully chosen to minimize the number of parameters
you must supply in most cases, especially if <tt>BaseType</tt> is an
you must supply in most cases, especially if <tt>Base</tt> is an
iterator.
<table border="1" summary="iterator_adaptor template parameters">
@ -183,17 +193,26 @@ struct iterator_adaptor;
<th>Description
<tr>
<td><tt>BaseType</tt>
<th>Requirements
<td>The type being wrapped.
<tr>
<td><tt>Base</tt>
<td>The data type on which the resulting iterator is based. Do
not be misled by the name &quot;Base&quot;: this is not a base
class.
<td>
<a href="http://www.sgi.com/tech/stl/Assignable.html">Assignable</a>,
<a href="http://www.sgi.com/tech/stl/DefaultConstructible.html">Default&nbsp;Constructible</a>
<tr>
<td><tt>Policies</tt>
<td>A <a href="../../more/generic_programming.html#policy">policy
class</a> that supplies core functionality to the resulting iterator. A
detailed description can be found <a href="#policies">below</a>.
class</a> that supplies core functionality to the resulting iterator.
<td>See table <a href="#policies">below</a>.
<tr>
<td><tt>Value</tt>
@ -204,7 +223,7 @@ struct iterator_adaptor;
"#1">[1]</a>. If the <tt>value_type</tt> you wish to use is an abstract
base class see note <a href="#5">[5]</a>.<br>
<b>Default:</b>
<tt>std::iterator_traits&lt;BaseType&gt;::value_type</tt> <a href=
<tt>std::iterator_traits&lt;Base&gt;::value_type</tt> <a href=
"#2">[2]</a>
<tr>
@ -214,29 +233,52 @@ struct iterator_adaptor;
particular, the result type of <tt>operator*()</tt>.<br>
<b>Default:</b> If <tt>Value</tt> is supplied, <tt>Value&amp;</tt> is
used. Otherwise
<tt>std::iterator_traits&lt;BaseType&gt;::reference</tt> is used. <a href="#7">[7]</a>
<tt>std::iterator_traits&lt;Base&gt;::reference</tt> is used. <a href="#7">[7]</a>
<td><a
href="http://www.sgi.com/tech/stl/ForwardIterator.html">ForwardIterators</a>,
<a
href="http://www.sgi.com/tech/stl/BidirectionalIterator.html">BidirectionalIterators</a>,
and <a
href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">RandomAccessIterators</a>
require that Reference is a true reference type (e.g. not a proxy).
<tr>
<td><tt>Pointer</tt>
<td>The <tt>pointer</tt> type of the resulting iterator, and in
particular, the result type of <tt>operator-&gt;()</tt>.<br>
<b>Default:</b> If <tt>Value</tt> was supplied, then <tt>Value*</tt>,
otherwise <tt>std::iterator_traits&lt;BaseType&gt;::pointer</tt>. <a href="#7">[7]</a>
<b>Default:</b> If <tt>Value</tt> was not supplied, <tt>std::iterator_traits&lt;Base&gt;::pointer</tt>. <a
href="#7">[7]</a> Otherwise, if <code>iterator_category</code> is
<code>input_iterator</code>, then a class yielding
<tt>Value*</tt> when <code>operator-&gt;()</code> is applied.
Otherwise, <tt>Value*</tt>.
<td><code>value_type*</code> or a
class which yields <code>value_type*</code> when
<code>operator-&gt;()</code> is applied.
<tr>
<td><tt>Category</tt>
<td>The <tt>iterator_category</tt> type for the resulting iterator.<br>
<b>Default:</b>
<tt>std::iterator_traits&lt;BaseType&gt;::iterator_category</tt>
<tt>std::iterator_traits&lt;Base&gt;::iterator_category</tt>
<td>One of
<code>std::input_iterator_tag</code>,
<code>std::output_iterator_tag</code>,
<code>std::forward_iterator_tag</code>,
<code>std::bidirectional_iterator_tag</code>, or
<code>std::random_access_iterator_tag</code>.
<tr>
<td><tt>Distance</tt>
<td>The <tt>difference_type</tt> for the resulting iterator.<br>
<b>Default:</b>
<tt>std::iterator_traits&lt;BaseType&gt;::difference_type</tt>
<tt>std::iterator_traits&lt;Base&gt;::difference_type</tt>
<td>A signed integral type
<tr>
<td><tt>NamedParam</tt>
@ -299,12 +341,16 @@ typedef iterator_adaptor&lt;foo_iterator, foo_policies,
<table border="1" summary="iterator_adaptor Policies operations">
<caption>
<b>Core Iterator Operations</b><br>
<tt>T</tt>: adapted iterator type; <tt>p</tt>: object of type T; <tt>n</tt>: <tt>T::size_type</tt>; <tt>x</tt>: <tt>T::difference_type</tt>; <tt>p1</tt>, <tt>p2</tt>: iterators
<b>Policies Class Requirements</b><br>
<tt><b>T</b></tt>: adapted iterator type; <tt><b>x, y</b></tt>: objects of type
T; <tt><b>p</b></tt>: <tt>T::policies_type</tt>
<tt><b>d</b></tt>:
<tt>T::difference_type</tt>; <tt><b>i1</b></tt>, <tt><b>i2</b></tt>:
<tt>T::base_type</tt>
</caption>
<tr>
<th>Operation
<th>Expression
<th>Effects
@ -313,7 +359,7 @@ typedef iterator_adaptor&lt;foo_iterator, foo_policies,
<th>Required for Iterator Categories
<tr>
<td><tt>initialize</tt>
<td nowrap><tt>p.initialize(b)</tt>
<td>optionally modify base iterator during iterator construction
@ -325,79 +371,66 @@ typedef iterator_adaptor&lt;foo_iterator, foo_policies,
"http://www.sgi.com/tech/stl/ForwardIterator.html">Forward</a>/ <a
href=
"http://www.sgi.com/tech/stl/BidirectionalIterator.html">Bidirectional</a>/
<a href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random
Access</a>
<a href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random&nbsp;Access</a>
<tr>
<td><tt>dereference</tt>
<td nowrap><tt>p.dereference(x)</tt>
<td>returns an element of the iterator's <tt>reference</tt> type
<td><tt>*p</tt>, <tt>p[n]</tt>
<td><tt>*x</tt>, <tt>x[d]</tt>
<tr>
<td><tt>equal</tt>
<td nowrap><tt>p.equal(x, y)</tt>
<td>tests the iterator for equality
<td><tt>p1&nbsp;==&nbsp;p2</tt>, <tt>p1&nbsp;!=&nbsp;p2</tt>
<td><tt>i1&nbsp;==&nbsp;i2</tt>, <tt>i1&nbsp;!=&nbsp;i2</tt>
<tr>
<td><tt>increment</tt>
<td nowrap><tt>p.increment(x)</tt>
<td>increments the iterator
<td><tt>++p</tt>, <tt>p++</tt>
<td><tt>++x</tt>, <tt>x++</tt>
<tr>
<td><tt>decrement</tt>
<td nowrap><tt>p.decrement(x)</tt>
<td>decrements the iterator
<td><tt>--p</tt>, <tt>p--</tt>
<td><tt>--x</tt>, <tt>x--</tt>
<td><a href=
"http://www.sgi.com/tech/stl/BidirectionalIterator.html">Bidirectional</a>/
<a href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random
Access</a>
<a href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random&nbsp;Access</a>
<tr>
<td><tt>less</tt>
<td>imposes a <a href=
"http://www.sgi.com/tech/stl/StrictWeakOrdering.html">Strict Weak
Ordering</a> relation on iterators
<td>
<tt>p1&nbsp;&lt;&nbsp;p2</tt>,
<tt>p1&nbsp;&lt;=&nbsp;p2</tt>,
<tt>p1&nbsp;&gt;&nbsp;p2</tt>,
<tt>p1&nbsp;&gt;=&nbsp;p2</tt>
<td rowspan="3"><a href=
"http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random
Access</a>
<tr>
<td><tt>distance</tt>
<td nowrap><tt>p.distance(x, y)</tt>
<td>measures the distance between iterators
<td><tt>p1 - p2</tt>
<td><tt>y&nbsp;-&nbsp;x</tt>, <tt>x&nbsp;&lt;&nbsp;y</tt>
<td rowspan="2"><a href=
"http://www.sgi.com/tech/stl/RandomAccessIterator.html">Random
Access</a>
<tr>
<td><tt>advance</tt>
<td nowrap><tt>p.advance(x, n)</tt>
<td>adds an integer offset to iterators
<td>
<tt>p&nbsp;+&nbsp;x</tt>,
<tt>x&nbsp;+&nbsp;p</tt>,
<tt>p&nbsp;+=&nbsp;x</tt>,
<tt>p&nbsp;-&nbsp;x</tt>,
<tt>p&nbsp;-=&nbsp;x</tt>
<tt>x&nbsp;+&nbsp;d</tt>,
<tt>d&nbsp;+&nbsp;x</tt>,
<br>
<tt>x&nbsp;+=&nbsp;d</tt>,
<tt>x&nbsp;-&nbsp;d</tt>,<br>
<tt>x&nbsp;-=&nbsp;d</tt>
</table>
@ -488,9 +521,24 @@ struct <a name="default_iterator_policies">default_iterator_policies</a>
Requires: <tt>B</tt> is convertible to <tt>Base</tt>.
<tr>
<td><tt>base_type base() const;</tt>
<td><tt>const base_type& base() const;</tt>
<br><br>
Return a const reference to the base object.
<tr> <td><tt>base_type& base();</tt>
<br><br>
Return a copy of the base object.
Return a reference to the base object. This is to give the policies object
access to the base object. See <a href="#policies">above</a> for policies
iterator_adaptor interaction.<a href="#8">[8]</a>
<tr>
<td><tt>const Policies& policies() const;</tt>
<br><br>
Return a const reference to the policies object.
<tr> <td><tt>Policies& policies();</tt>
<br><br>
Return a reference to the policies object.
</table>
<h3><a name="example">Example</a></h3>
@ -508,7 +556,7 @@ struct <a name="default_iterator_policies">default_iterator_policies</a>
argument and that we'll need to be able to deduce the <tt>result_type</tt>
of the function so we can use it for the adapted iterator's
<tt>value_type</tt>. <a href=
"http://www.sgi.com/Technology/STL/AdaptableUnaryFunction.html">AdaptableUnaryFunction</a>
"http://www.sgi.com/tech/stl/AdaptableUnaryFunction.html">AdaptableUnaryFunction</a>
is the <a href="../../more/generic_programming.html#concept">Concept</a>
that fulfills those requirements.
@ -657,7 +705,7 @@ int main(int, char*[])
<li>Interoperable iterators can be freely mixed in comparison expressions
so long as the <tt>Policies</tt> class has <tt>equal</tt> (and, for
random access iterators, <tt>less</tt>) members that can accept both
random access iterators, <tt>distance</tt>) members that can accept both
<tt>Base</tt> types in either order.
<li>Interoperable iterators can be freely mixed in subtraction
@ -711,11 +759,12 @@ they share the same <tt>Policies</tt> and since <tt>Category</tt> and
the projection <tt>const_iterator</tt>.
<li> Since <tt>projection_iterator_policies</tt> implements only the
<tt>dereference</tt> operation, and inherits all other behaviors from <tt><a
href="#default_iterator_policies">default_iterator_policies</a></tt>, which has
fully-templatized <tt>equal</tt>, <tt>less</tt>, and <tt>distance</tt>
operations, the <tt>iterator</tt> and <tt>const_iterator</tt> can be freely
mixed in comparison and subtraction expressions.
<tt>dereference</tt> operation, and inherits all other behaviors from
<tt><a
href="#default_iterator_policies">default_iterator_policies</a></tt>,
which has fully-templatized <tt>equal</tt> and <tt>distance</tt>
operations, the <tt>iterator</tt> and <tt>const_iterator</tt> can be
freely mixed in comparison and subtraction expressions.
</ul>
@ -723,7 +772,7 @@ mixed in comparison and subtraction expressions.
<p>There is an unlimited number of ways the <tt>iterator_adaptors</tt>
class can be used to create iterators. One interesting exercise would be to
re-implement the iterators of <tt>std::list</tt> and <tt>std::slist</tt>
re-implement the iterators of <tt>std::list</tt> and <tt>slist</tt>
using <tt>iterator_adaptors</tt>, where the adapted <tt>Iterator</tt> types
would be node pointers.
@ -760,7 +809,8 @@ struct iterator_adaptor
iterator_adaptor();
explicit iterator_adaptor(const Base&amp;, const Policies&amp; = Policies());
base_type base() const;
base_type& base();
const base_type& base() const;
template &lt;class B, class V, class R, class P&gt;
iterator_adaptor(
@ -805,6 +855,19 @@ bool operator==(const iterator_adaptor&lt;B1,P,V1,R1,P1,C,D&gt;&amp;,
// and similarly for operators !=, &lt;, &lt;=, &gt;=, &gt;
</pre>
<h3><a name="portability">Portability</a></h3>
<p>Generally, the iterator adaptors library can be compiled with all compilers
supporting iterator traits and type traits.</p>
<p>Microsoft VC++ is not able to handle iterator adaptors based on a
<code>vector<T>::iterator</code> without specifying all template paramters explicitly.
In case not all template parameters are specified explicitly, the iterator adaptors
library will deduce these types using iterator_traits. But since in VC++ a
<code>vector<T>::iterator</code> is a <code>T*</code>, VC++ can't handle using
iterator_traits due to the lack of partial template specialization.</p>
<h3><a name="notes">Notes</a></h3>
<p><a name="1">[1]</a> The standard specifies that the <tt>value_type</tt>
@ -891,11 +954,15 @@ bool operator==(const iterator_adaptor&lt;B1,P,V1,R1,P1,C,D&gt;&amp;,
<tt>Base</tt> type is a const pointer, then the correct defaults
for the <tt>reference</tt> and <tt>pointer</tt> types can not be
deduced. You must specify these types explicitly.
<p><a name="8">[8]</a>
Exposing the base object might be considered as being dangerous.
A possible fix would require compiler support for template friends.
As this is not widely available today, the base object remains exposed for now.
<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" -->
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->30 Nov 2001<!--webbot bot="Timestamp" endspan i-checksum="15239" -->
<p>&copy; Copyright Dave Abrahams and Jeremy Siek 2001. Permission to copy,

View File

@ -85,15 +85,17 @@ template <class Iterator,
struct non_portable_tests
{
// Unfortunately, the VC6 standard library doesn't supply these :(
typedef typename boost::detail::iterator_traits<Iterator>::pointer test_pt;
typedef typename boost::detail::iterator_traits<Iterator>::reference test_rt;
BOOST_STATIC_ASSERT((
boost::is_same<
typename boost::detail::iterator_traits<Iterator>::pointer,
::boost::is_same<
test_pt,
pointer
>::value));
BOOST_STATIC_ASSERT((
boost::is_same<
typename boost::detail::iterator_traits<Iterator>::reference,
::boost::is_same<
test_rt,
reference
>::value));
};
@ -102,15 +104,17 @@ 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;
BOOST_STATIC_ASSERT((
boost::is_same<
typename boost::detail::iterator_traits<Iterator>::difference_type,
::boost::is_same<
test_dt,
difference_type
>::value));
BOOST_STATIC_ASSERT((
boost::is_same<
typename boost::detail::iterator_traits<Iterator>::iterator_category,
::boost::is_same<
test_cat,
category
>::value));
};
@ -121,9 +125,10 @@ template <class Iterator,
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;
BOOST_STATIC_ASSERT((
boost::is_same<
typename boost::detail::iterator_traits<Iterator>::value_type,
::boost::is_same<
test_vt,
value_type
>::value));
};

View File

@ -75,6 +75,12 @@ protected:
}; // 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*>
class test_opr
: public test_opr_base
@ -94,7 +100,8 @@ public:
private:
// Test data
static iter_type const fruit_begin, fruit_end;
static iter_type const fruit_begin;
static iter_type const fruit_end;
// Test parts
static void post_increment_test();
@ -117,12 +124,12 @@ 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( fruit );
typename test_opr<T, R, P>::iter_type const
test_opr<T, R, P>::fruit_begin = test_iter<T,R,P>( fruit );
template <typename T, typename R, typename P>
typename test_opr<T, R, P>::iter_type const
test_opr<T, R, P>::fruit_end( fruit + fruit_length );
test_opr<T, R, P>::fruit_end = test_iter<T,R,P>( fruit + fruit_length );
// Main testing function

View File

@ -20,7 +20,7 @@
namespace
{
class DontTreadOnMe : boost::noncopyable
class DontTreadOnMe : private boost::noncopyable
{
public:
DontTreadOnMe() { std::cout << "defanged!" << std::endl; }
@ -35,4 +35,4 @@ int main()
object1 = object2;
return 0;
} // main

View File

@ -347,7 +347,7 @@ void test(Number* = 0)
// factoring out difference_type for the assert below confused Borland :(
typedef boost::detail::is_signed<
#ifndef BOOST_MSVC
#if !defined(BOOST_MSVC) || BOOST_MSVC > 1300
typename
#endif
boost::detail::numeric_traits<Number>::difference_type

View File

@ -30,7 +30,11 @@ provided by the class.</p>
</ul></li>
<li><a href="#usage">Usage</a>
<ul>
<li><a href="#two_arg">Two-Argument Template Forms</a></li>
<li><a href="#two_arg">Two-Argument Template Forms</a>
<ul>
<li><a href="#two_arg_gen">General Considerations</a></li>
<li><a href="#mixed_arithmetics">Mixed arithmetics</a></li>
</ul></li>
<li><a href="#chaining">Base Class Chaining and Object Size</a></li>
<li><a href="#explicit_instantiation">Separate, Explicit
Instantiation</a></li>
@ -39,7 +43,10 @@ provided by the class.</p>
<li><a href="#example">Example</a></li>
<li><a href="#arithmetic">Arithmetic operators</a>
<ul>
<li><a href="#smpl_oprs">Simple Arithmetic Operators</a></li>
<li><a href="#smpl_oprs">Simple Arithmetic Operators</a>
<ul>
<li><a href="#ordering">Ordering Note</a></li>
</ul></li>
<li><a href="#grpd_oprs">Grouped Arithmetic Operators</a></li>
<li><a href="#ex_oprs">Example Templates</a></li>
<li><a href="#a_demo">Arithmetic Operators Demonstration
@ -49,8 +56,12 @@ provided by the class.</p>
Helpers</a>
<ul>
<li><a href="#dereference">Dereference operators</a></li>
<li><a href="#iterator">Iterator Helpers</a></li>
<li><a href="#iterator_helpers_notes">Iterator Helper Notes</a></li>
<li><a href="#grpd_iter_oprs">Grouped Iterator Operators</a></li>
<li><a href="#iterator">Iterator Helpers</a>
<ul>
<li><a href="#iterator_helpers_notes">Iterator Helper
Notes</a></li>
</ul></li>
<li><a href="#i_demo">Iterator Demonstration and Test
Program</a></li>
</ul></li>
@ -151,6 +162,8 @@ domains, <i>i.e.</i> eventually more useful.</p>
<h3><a name="two_arg">Two-Argument</a> Template Forms</h3>
<h4><a name="two_arg_gen">General Considerations</a></h4>
<p>The arguments to a binary operator commonly have identical types, but
it is not unusual to want to define operators which combine different
types. For <a href="#example">example</a>, one might want to multiply a
@ -176,6 +189,46 @@ trailing <code>'1'</code> are provided for symmetry and to enable
certain applications of the <a href="#chaining">base class chaining</a>
technique.</p>
<h4><a name="mixed_arithmetics">Mixed Arithmetics</a></h4>
<p>Another application of the two-argument template forms is for
mixed arithmetics between a type <code>T</code> and a type <code>U</code>
that is convertible to <code>T</code>. In this case there are two ways
where the two-argument template forms are helpful: one is to provide
the respective signatures for operator overloading, the second is
performance.</p>
<p>With respect to the operator overloading assume <i>e.g.</i> that
<code>U</code> is <code>int</code>, that <code>T</code> is an user-defined
unlimited integer type, and that <code>double operator-(double, const
T&amp;)</code> exists. If one wants to compute <code>int - T</code> and
does not provide <code>T operator-(int, const T&amp;)</code>, the
compiler will consider <code>double operator-(double, const T&amp;)</code>
to be a better match than <code>T operator-(const T&amp;, const
T&amp;)</code>, which will probably be different from the user's intention.
To define a complete set of operator signatures, additional 'left' forms
of the two-argument template forms are provided (<code><a
href="#subtractable2_left">subtractable2_left&lt;T, U&gt;</a></code>,
<code><a href="#dividable2_left">dividable2_left&lt;T, U&gt;</a></code>,
<code><a href="#modable2_left">modable2_left&lt;T, U&gt;</a></code>) that
define the signatures for non-commutative operators where <code>U</code>
appears on the left hand side (<code>operator-(const U&amp;, const
T&amp;)</code>, <code>operator/(const U&amp;, const T&amp;)</code>,
<code>operator%(const U&amp;, const T&amp;)</code>).</p>
<p>With respect to the performance observe that when one uses the
single type binary operator for mixed type arithmetics, the type
<code>U</code> argument has to be converted to type <code>T</code>. In
practice, however, there are often more efficient implementations of,
say <code>T::operator-=(const U&amp;)</code> that avoid unnecessary
conversions from <code>U</code> to <code>T</code>. The two-argument
template forms of the arithmetic operator create additional operator
interfaces that use these more efficient implementations. There is, however,
no performance gain in the 'left' forms: they still need a conversion
from <code>U</code> to <code>T</code> and have an implementation
equivalent to the code that would be automatically created by the compiler
if it considered the single type binary operator to be the best match.</p>
<h3>Base Class <a name="chaining">Chaining</a> and Object Size</h3>
<p>Every operator class template, except the <a href="#ex_oprs">arithmetic
@ -419,6 +472,12 @@ for the <a href="#chaining">base class chaining</a> technique.
<td><code>t -= u</code>.<br>
Return convertible to <code>T</code>.</td>
</tr>
<tr>
<td><code><a name="subtractable2_left">subtractable2_left&lt;T, U&gt;</a></code></td>
<td><code>T operator-(const U&amp;, const T&amp;)</code></td>
<td><code>T temp(u); temp -= t</code>.<br>
Return convertible to <code>T</code>.</td>
</tr>
<tr>
<td><code><a name="multipliable1">multipliable&lt;T&gt;</a></code><br>
<code>multipliable1&lt;T&gt;</code></td>
@ -448,6 +507,12 @@ for the <a href="#chaining">base class chaining</a> technique.
<td><code>t /= u</code>.<br>
Return convertible to <code>T</code>.</td>
</tr>
<tr>
<td><code><a name="dividable2_left">dividable2_left&lt;T, U&gt;</a></code></td>
<td><code>T operator/(const U&amp;, const T&amp;)</code></td>
<td><code>T temp(u); temp /= t</code>.<br>
Return convertible to <code>T</code>.</td>
</tr>
<tr>
<td><code><a name="modable1">modable&lt;T&gt;</a></code><br>
<code>modable1&lt;T&gt;</code></td>
@ -462,6 +527,12 @@ for the <a href="#chaining">base class chaining</a> technique.
<td><code>t %= u</code>.<br>
Return convertible to <code>T</code>.</td>
</tr>
<tr>
<td><code><a name="modable2_left">modable2_left&lt;T, U&gt;</a></code></td>
<td><code>T operator%(const U&amp;, const T&amp;)</code></td>
<td><code>T temp(u); temp %= t</code>.<br>
Return convertible to <code>T</code>.</td>
</tr>
<tr>
<td><code><a name="orable1">orable&lt;T&gt;</a></code><br>
<code>orable1&lt;T&gt;</code></td>
@ -588,8 +659,9 @@ for the <a href="#chaining">base class chaining</a> technique.
</tr>
</table>
<p><strong><a name="ordering">Ordering Note</a></strong><br>
The <code><a href="#less_than_comparable1">less_than_comparable&lt;T&gt;</a></code>
<h4><a name="ordering">Ordering</a> Note</h4>
<p>The <code><a href="#less_than_comparable1">less_than_comparable&lt;T&gt;</a></code>
and <code><a href="#partially_ordered1">partially_ordered&lt;T&gt;</a></code>
templates provide the same set of operations. However, the workings of
<code><a href="#less_than_comparable1">less_than_comparable&lt;T&gt;</a></code>
@ -771,6 +843,109 @@ optional template parameter <code>B</code>, which is not shown, for the
<li><code><a href="#right_shiftable2">right_shiftable&lt;T, U&gt;</a></code></li>
</ul></td>
</tr>
<tr>
<td><code><a name="ring_operators1">ring_operators&lt;T&gt;</a></code><br>
<code>ring_operators1&lt;T&gt;</code></td>
<td><ul>
<li><code><a href="#additive1">additive&lt;T&gt;</a></code></li>
<li><code><a href="#multipliable1">multipliable&lt;T&gt;</a></code></li>
</ul></td>
</tr>
<tr>
<td><code><a name="ring_operators2">ring_operators&lt;T, U&gt;</a></code><br>
<code>ring_operators2&lt;T, U&gt;</code></td>
<td><ul>
<li><code><a href="#additive2">additive&lt;T, U&gt;</a></code></li>
<li><code><a href="#subtractable2_left">subtractable2_left&lt;T, U&gt;</a></code></li>
<li><code><a href="#multipliable2">multipliable&lt;T, U&gt;</a></code></li>
</ul></td>
</tr>
<tr>
<td><code><a name="ordered_ring_operators1">ordered_ring_operators&lt;T&gt;</a></code><br>
<code>ordered_ring_operators1&lt;T&gt;</code></td>
<td><ul>
<li><code><a href="#ring_operators1">ring_operators&lt;T&gt;</a></code></li>
<li><code><a href="#totally_ordered1">totally_ordered&lt;T&gt;</a></code></li>
</ul></td>
</tr>
<tr>
<td><code><a name="ordered_ring_operators2">ordered_ring_operators&lt;T, U&gt;</a></code><br>
<code>ordered_ring_operators2&lt;T, U&gt;</code></td>
<td><ul>
<li><code><a href="#ring_operators2">ring_operators&lt;T, U&gt;</a></code></li>
<li><code><a href="#totally_ordered2">totally_ordered&lt;T, U&gt;</a></code></li>
</ul></td>
</tr>
<tr>
<td><code><a name="field_operators1">field_operators&lt;T&gt;</a></code><br>
<code>field_operators1&lt;T&gt;</code></td>
<td><ul>
<li><code><a href="#ring_operators1">ring_operators&lt;T&gt;</a></code></li>
<li><code><a href="#dividable1">dividable&lt;T&gt;</a></code></li>
</ul></td>
</tr>
<tr>
<td><code><a name="field_operators2">field_operators&lt;T, U&gt;</a></code><br>
<code>field_operators2&lt;T, U&gt;</code></td>
<td><ul>
<li><code><a href="#ring_operators2">ring_operators&lt;T, U&gt;</a></code></li>
<li><code><a href="#dividable2">dividable&lt;T, U&gt;</a></code></li>
<li><code><a href="#dividable2_left">dividable2_left&lt;T, U&gt;</a></code></li>
</ul></td>
</tr>
<tr>
<td><code><a name="ordered_field_operators1">ordered_field_operators&lt;T&gt;</a></code><br>
<code>ordered_field_operators1&lt;T&gt;</code></td>
<td><ul>
<li><code><a href="#field_operators1">field_operators&lt;T&gt;</a></code></li>
<li><code><a href="#totally_ordered1">totally_ordered&lt;T&gt;</a></code></li>
</ul></td>
</tr>
<tr>
<td><code><a name="ordered_field_operators2">ordered_field_operators&lt;T, U&gt;</a></code><br>
<code>ordered_field_operators2&lt;T, U&gt;</code></td>
<td><ul>
<li><code><a href="#field_operators2">field_operators&lt;T, U&gt;</a></code></li>
<li><code><a href="#totally_ordered2">totally_ordered&lt;T, U&gt;</a></code></li>
</ul></td>
</tr>
<tr>
<td><code><a name="euclidian_ring_operators1">euclidian_ring_operators&lt;T&gt;</a></code><br>
<code>euclidian_ring_operators1&lt;T&gt;</code></td>
<td><ul>
<li><code><a href="#ring_operators1">ring_operators&lt;T&gt;</a></code></li>
<li><code><a href="#dividable1">dividable&lt;T&gt;</a></code></li>
<li><code><a href="#modable1">modable&lt;T&gt;</a></code></li>
</ul></td>
</tr>
<tr>
<td><code><a name="euclidian_ring_operators2">euclidian_ring_operators&lt;T, U&gt;</a></code><br>
<code>euclidian_ring_operators2&lt;T, U&gt;</code></td>
<td><ul>
<li><code><a href="#ring_operators2">ring_operators&lt;T, U&gt;</a></code></li>
<li><code><a href="#dividable2">dividable&lt;T, U&gt;</a></code></li>
<li><code><a href="#dividable2_left">dividable2_left&lt;T, U&gt;</a></code></li>
<li><code><a href="#modable2">modable&lt;T, U&gt;</a></code></li>
<li><code><a href="#modable2_left">modable2_left&lt;T, U&gt;</a></code></li>
</ul></td>
</tr>
<tr>
<td><code><a name="ordered_euclidian_ring_operators1">ordered_euclidian_ring_operators&lt;T&gt;</a></code><br>
<code>ordered_euclidian_ring_operators1&lt;T&gt;</code></td>
<td><ul>
<li><code><a href="#euclidian_ring_operators1">euclidian_ring_operators&lt;T&gt;</a></code></li>
<li><code><a href="#totally_ordered1">totally_ordered&lt;T&gt;</a></code></li>
</ul></td>
</tr>
<tr>
<td><code><a name="ordered_euclidian_ring_operators2">ordered_euclidian_ring_operators&lt;T, U&gt;</a></code><br>
<code>ordered_euclidian_ring_operators2&lt;T, U&gt;</code></td>
<td><ul>
<li><code><a href="#euclidian_ring_operators2">euclidian_ring_operators&lt;T, U&gt;</a></code></li>
<li><code><a href="#totally_ordered2">totally_ordered&lt;T, U&gt;</a></code></li>
</ul></td>
</tr>
</table>
<h3><a name="ex_oprs">Example</a> Templates</h3>
@ -888,19 +1063,87 @@ href="#chaining">base class chaining</a>.</p>
</tr>
</table>
<h3><a name="iterator">Iterator</a> Helpers</h3>
<h3><a name="grpd_iter_oprs">Grouped Iterator Operators</a></h3>
<p>There are five separate iterator helper classes, each for a
different category of iterator. Here is a summary of the core set of
operators that the custom iterator must define, and the extra operators
that are created by the helper classes. These classes cannot be used for <a
href="#chaining">base class chaining</a>. For convenience, the helper
classes also fill in all of the typedef's required of iterators by the
C++ standard (<code>iterator_category</code>, <code>value_type</code>,
<i>etc.</i>).</p>
<p>There are five iterator operator class templates, each for a different
category of iterator. The following table shows the operator groups
for any category that a custom iterator could define. These class
templates have an additional optional template parameter <code>B</code>,
which is not shown, to support <a href="#chaining">base class chaining</a>.</p>
<table cellpadding="5" border="1" align="center">
<caption>Iterator Helper Template Classes</caption>
<caption>Iterator Operator Class Templates</caption>
<tr>
<td colspan="2"><table align="center" border="1">
<caption><em>Key</em></caption>
<tr>
<td><code>T</code>: operand type</td>
<td><code>P</code>: <code>pointer</code> type</td>
</tr>
<tr>
<td><code>D</code>: <code>difference_type</code></td>
<td><code>R</code>: <code>reference</code> type</td>
</tr>
<tr>
<td><code>V</code>: <code>value_type</code></td>
<td></td>
</tr>
</table></td>
</tr>
<tr>
<th>Template</th>
<th>Component Operator Templates</th>
</tr>
<tr>
<td><code><a name="input_iteratable">input_iteratable&lt;T, P&gt;</a></code></td>
<td><ul>
<li><code><a href="#equality_comparable1">equality_comparable&lt;T&gt;</a></code></li>
<li><code><a href="#incrementable">incrementable&lt;T&gt;</a></code></li>
<li><code><a href="#dereferenceable">dereferenceable&lt;T, P&gt;</a></code></li>
</ul></td>
</tr>
<tr>
<td><code><a name="output_iteratable">output_iteratable&lt;T&gt;</a></code></td>
<td><ul>
<li><code><a href="#incrementable">incrementable&lt;T&gt;</a></code></li>
</ul></td>
</tr>
<tr>
<td><code><a name="forward_iteratable">forward_iteratable&lt;T, P&gt;</a></code></td>
<td><ul>
<li><code><a href="#input_iteratable">input_iteratable&lt;T, P&gt;</a></code></li>
</ul></td>
</tr>
<tr>
<td><code><a name="bidirectional_iteratable">bidirectional_iteratable&lt;T, P&gt;</a></code></td>
<td><ul>
<li><code><a href="#forward_iteratable">forward_iteratable&lt;T, P&gt;</a></code></li>
<li><code><a href="#decrementable">decrementable&lt;T&gt;</a></code></li>
</ul></td>
</tr>
<tr>
<td><code><a name="random_access_iteratable">random_access_iteratable&lt;T, P, D, R&gt;</a></code></td>
<td><ul>
<li><code><a href="#bidirectional_iteratable">bidirectional_iteratable&lt;T, P&gt;</a></code></li>
<li><code><a href="#totally_ordered1">totally_ordered&lt;T&gt;</a></code></li>
<li><code><a href="#additive2">additive&lt;T, D&gt;</a></code></li>
<li><code><a href="#indexable">indexable&lt;T, D, R&gt;</a></code></li>
</ul></td>
</tr>
</table>
<h3><a name="iterator">Iterator</a> Helpers</h3>
<p>There are also five iterator helper class templates, each corresponding
to a different iterator category. These classes cannot be used for <a
href="#chaining">base class chaining</a>. The following summaries
show that these class templates supply both the iterator operators from
the <a href="#grpd_iter_oprs">iterator operator class templates</a> and
the iterator typedef's required by the C++ standard (<code>iterator_category</code>,
<code>value_type</code>, <i>etc.</i>).</p>
<table cellpadding="5" border="1" align="center">
<caption>Iterator Helper Class Templates</caption>
<tr>
<td colspan="2"><table align="center" border="1">
<caption><em>Key</em></caption>
@ -926,16 +1169,14 @@ C++ standard (<code>iterator_category</code>, <code>value_type</code>,
<td><code><a name="input_iterator_helper">input_iterator_helper&lt;T, V, D, P, R&gt;</a></code></td>
<td>Supports the operations and has the requirements of
<ul>
<li><code><a href="#equality_comparable1">equality_comparable&lt;T&gt;</a></code></li>
<li><code><a href="#incrementable">incrementable&lt;T&gt;</a></code></li>
<li><code><a href="#dereferenceable">dereferenceable&lt;T, P&gt;</a></code></li>
<li><code><a href="#input_iteratable">input_iteratable&lt;T, P&gt;</a></code></li>
</ul></td>
</tr>
<tr valign="baseline">
<td><code><a name="output_iterator_helper">output_iterator_helper&lt;T&gt;</a></code></td>
<td>Supports the operations and has the requirements of
<ul>
<li><code><a href="#incrementable">incrementable&lt;T&gt;</a></code></li>
<li><code><a href="#output_iteratable">output_iteratable&lt;T&gt;</a></code></li>
</ul>
See also [<a href="#1">1</a>], [<a href="#2">2</a>].
</td>
@ -944,33 +1185,21 @@ C++ standard (<code>iterator_category</code>, <code>value_type</code>,
<td><code><a name="forward_iterator_helper">forward_iterator_helper&lt;T, V, D, P, R&gt;</a></code></td>
<td>Supports the operations and has the requirements of
<ul>
<li><code><a href="#equality_comparable1">equality_comparable&lt;T&gt;</a></code></li>
<li><code><a href="#incrementable">incrementable&lt;T&gt;</a></code></li>
<li><code><a href="#dereferenceable">dereferenceable&lt;T, P&gt;</a></code></li>
<li><code><a href="#forward_iteratable">forward_iteratable&lt;T, P&gt;</a></code></li>
</ul></td>
</tr>
<tr valign="baseline">
<td><code><a name="bidirectional_iterator_helper">bidirectional_iterator_helper&lt;T, V, D, P, R&gt;</a></code></td>
<td>Supports the operations and has the requirements of
<ul>
<li><code><a href="#equality_comparable1">equality_comparable&lt;T&gt;</a></code></li>
<li><code><a href="#incrementable">incrementable&lt;T&gt;</a></code></li>
<li><code><a href="#decrementable">decrementable&lt;T&gt;</a></code></li>
<li><code><a href="#dereferenceable">dereferenceable&lt;T, P&gt;</a></code></li>
<li><code><a href="#bidirectional_iteratable">bidirectional_iteratable&lt;T, P&gt;</a></code></li>
</ul></td>
</tr>
<tr valign="baseline">
<td><code><a name="random_access_iterator_helper">random_access_iterator_helper&lt;T, V, D, P, R&gt;</a></code></td>
<td>Supports the operations and has the requirements of
<ul>
<li><code><a href="#equality_comparable1">equality_comparable&lt;T&gt;</a></code></li>
<li><code><a href="#less_than_comparable1">less_than_comparable&lt;T&gt;</a></code></li>
<li><code><a href="#incrementable">incrementable&lt;T&gt;</a></code></li>
<li><code><a href="#decrementable">decrementable&lt;T&gt;</a></code></li>
<li><code><a href="#dereferenceable">dereferenceable&lt;T, P&gt;</a></code></li>
<li><code><a href="#addable2">addable&lt;T, D&gt;</a></code></li>
<li><code><a href="#subtractable2">subtractable&lt;T, D&gt;</a></code></li>
<li><code><a href="#indexable">indexable&lt;T, D, R&gt;</a></code></li>
<li><code><a href="#random_access_iteratable">random_access_iteratable&lt;T, P, D, R&gt;</a></code></li>
</ul>
To satisfy <cite><a href="http://www.sgi.com/tech/stl/RandomAccessIterator.html">RandomAccessIterator</a></cite>,
<code>x1 - x2</code> with return convertible to <code>D</code>
@ -978,7 +1207,7 @@ C++ standard (<code>iterator_category</code>, <code>value_type</code>,
</tr>
</table>
<h3><a name="iterator_helpers_notes">Iterator Helper Notes</a></h3>
<h4><a name="iterator_helpers_notes">Iterator Helper Notes</a></h4>
<p><a name="1">[1]</a> Unlike other iterator helpers templates,
<code>output_iterator_helper</code> takes only one template parameter - the type of
@ -987,8 +1216,8 @@ restriction, the standard requires <code>difference_type</code> and
<code>value_type</code> of any output iterator to be
<code>void</code> (24.3.1 [lib.iterator.traits]), and
<code>output_iterator_helper</code> template respects this
requirement. Also, output iterators in the standard have void <tt>pointer</tt> and
<tt>reference</tt> types, so the <tt>output_iterator_helper</tt> does the
requirement. Also, output iterators in the standard have void <code>pointer</code> and
<code>reference</code> types, so the <code>output_iterator_helper</code> does the
same.
<p><a name="2">[2]</a> As self-proxying is the easiest and most common way to
@ -1008,13 +1237,13 @@ template&lt;class UnaryFunction&gt;
struct function_output_iterator
: boost::output_iterator_helper&lt; function_output_iterator&lt;UnaryFunction&gt; &gt;
{
explicit function_output_iterator(UnaryFunction const& f = UnaryFunction())
explicit function_output_iterator(UnaryFunction const&amp; f = UnaryFunction())
: func(f) {}
template&lt;typename T&gt;
function_output_iterator& operator=(T const& value)
function_output_iterator&amp; operator=(T const&amp; value)
{
this->func(value);
this-&gt;func(value);
return *this;
}
@ -1093,6 +1322,10 @@ the test results with selected platforms.</p>
partial ordering, and arithmetic conversions. Added the
grouped operator classes. Added helper classes for
input and output iterators.
<dt>Helmut Zeisel
<dd>Contributed the 'left' operators and added some
grouped operator classes.
</dl>
<h2>Note for Users of <a name="old_lib_note">Older Versions</a></h2>
@ -1142,7 +1375,7 @@ the library remain backward-compatible.</p>
<hr>
<p>Revised: 25 Jun 2001</p>
<p>Revised: 30 Oct 2001</p>
<p>Copyright &copy; David Abrahams and Beman Dawes 1999-2001.
Permission to copy, use, modify, sell and distribute this document is

View File

@ -8,6 +8,8 @@
// See http://www.boost.org for most recent version including documentation.
// Revision History
// 01 Oct 01 Added tests for "left" operators
// and new grouped operators. (Helmut Zeisel)
// 20 May 01 Output progress messages. Added tests for new operator
// templates. Updated random number generator. Changed tests to
// use Boost Test Tools library. (Daryle Walker)
@ -184,6 +186,74 @@ namespace
template <class T, class U>
T true_value(Wrapped4<T,U> x) { return x.value(); }
// U must be convertible to T
template <class T, class U>
class Wrapped5
: boost::ordered_field_operators2<Wrapped5<T, U>, U>
, boost::ordered_field_operators1<Wrapped5<T, U> >
{
public:
explicit Wrapped5( T v = T() ) : _value(v) {}
// Conversion from U to Wrapped5<T,U>
Wrapped5(U u) : _value(u) {}
T value() const { return _value; }
bool operator<(const Wrapped5& x) const { return _value < x._value; }
bool operator<(U u) const { return _value < u; }
bool operator>(U u) const { return _value > u; }
bool operator==(const Wrapped5& u) const { return _value == u._value; }
bool operator==(U u) const { return _value == u; }
Wrapped5& operator/=(const Wrapped5& u) { _value /= u._value; return *this;}
Wrapped5& operator/=(U u) { _value /= u; return *this;}
Wrapped5& operator*=(const Wrapped5& u) { _value *= u._value; return *this;}
Wrapped5& operator*=(U u) { _value *= u; return *this;}
Wrapped5& operator-=(const Wrapped5& u) { _value -= u._value; return *this;}
Wrapped5& operator-=(U u) { _value -= u; return *this;}
Wrapped5& operator+=(const Wrapped5& u) { _value += u._value; return *this;}
Wrapped5& operator+=(U u) { _value += u; return *this;}
private:
T _value;
};
template <class T, class U>
T true_value(Wrapped5<T,U> x) { return x.value(); }
// U must be convertible to T
template <class T, class U>
class Wrapped6
: boost::ordered_euclidian_ring_operators2<Wrapped6<T, U>, U>
, boost::ordered_euclidian_ring_operators1<Wrapped6<T, U> >
{
public:
explicit Wrapped6( T v = T() ) : _value(v) {}
// Conversion from U to Wrapped6<T,U>
Wrapped6(U u) : _value(u) {}
T value() const { return _value; }
bool operator<(const Wrapped6& x) const { return _value < x._value; }
bool operator<(U u) const { return _value < u; }
bool operator>(U u) const { return _value > u; }
bool operator==(const Wrapped6& u) const { return _value == u._value; }
bool operator==(U u) const { return _value == u; }
Wrapped6& operator%=(const Wrapped6& u) { _value %= u._value; return *this;}
Wrapped6& operator%=(U u) { _value %= u; return *this;}
Wrapped6& operator/=(const Wrapped6& u) { _value /= u._value; return *this;}
Wrapped6& operator/=(U u) { _value /= u; return *this;}
Wrapped6& operator*=(const Wrapped6& u) { _value *= u._value; return *this;}
Wrapped6& operator*=(U u) { _value *= u; return *this;}
Wrapped6& operator-=(const Wrapped6& u) { _value -= u._value; return *this;}
Wrapped6& operator-=(U u) { _value -= u; return *this;}
Wrapped6& operator+=(const Wrapped6& u) { _value += u._value; return *this;}
Wrapped6& operator+=(U u) { _value += u; return *this;}
private:
T _value;
};
template <class T, class U>
T true_value(Wrapped6<T,U> x) { return x.value(); }
// MyInt uses only the single template-argument form of all_operators<>
typedef Wrapped1<int> MyInt;
@ -193,6 +263,10 @@ namespace
typedef Wrapped4<short, short> MyShort;
typedef Wrapped5<double, int> MyDoubleInt;
typedef Wrapped6<long, int> MyLongInt;
template <class X1, class Y1, class X2, class Y2>
void sanity_check(X1 x1, Y1 y1, X2 x2, Y2 y2)
{
@ -267,6 +341,13 @@ namespace
BOOST_TEST( (x1 - y1).value() == (x2 - y2) );
}
template <class X1, class Y1, class X2, class Y2>
void test_subtractable_left(X1 x1, Y1 y1, X2 x2, Y2 y2)
{
sanity_check( x1, y1, x2, y2 );
BOOST_TEST( (y1 - x1).value() == (y2 - x2) );
}
template <class X1, class Y1, class X2, class Y2>
void test_dividable(X1 x1, Y1 y1, X2 x2, Y2 y2)
{
@ -275,6 +356,14 @@ namespace
BOOST_TEST( (x1 / y1).value() == (x2 / y2) );
}
template <class X1, class Y1, class X2, class Y2>
void test_dividable_left(X1 x1, Y1 y1, X2 x2, Y2 y2)
{
sanity_check( x1, y1, x2, y2 );
if ( x2 != 0 )
BOOST_TEST( (y1 / x1).value() == (y2 / x2) );
}
template <class X1, class Y1, class X2, class Y2>
void test_modable(X1 x1, Y1 y1, X2 x2, Y2 y2)
{
@ -283,6 +372,14 @@ namespace
BOOST_TEST( (x1 % y1).value() == (x2 % y2) );
}
template <class X1, class Y1, class X2, class Y2>
void test_modable_left(X1 x1, Y1 y1, X2 x2, Y2 y2)
{
sanity_check( x1, y1, x2, y2 );
if ( x2 != 0 )
BOOST_TEST( (y1 % x1).value() == (y2 % x2) );
}
template <class X1, class Y1, class X2, class Y2>
void test_xorable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
{
@ -374,6 +471,14 @@ namespace
test_decrementable( x1, x2 );
}
template <class X1, class Y1, class X2, class Y2>
void test_left(X1 x1, Y1 y1, X2 x2, Y2 y2)
{
test_subtractable_left( x1, y1, x2, y2 );
test_dividable_left( x1, y1, x2, y2 );
test_modable_left( x1, y1, x2, y2 );
}
template <class Big, class Small>
struct tester
{
@ -388,6 +493,18 @@ namespace
}
};
template <class Big, class Small>
struct tester_left
{
void operator()(boost::minstd_rand& randomizer) const
{
Big b1 = Big( randomizer() );
Small s = Small( randomizer() );
test_left( Wrapped6<Big, Small>(b1), s, b1, s );
}
};
// added as a regression test. We had a bug which this uncovered.
struct Point
: boost::addable<Point
@ -427,6 +544,13 @@ template Wrapped2<unsigned int, unsigned char>;
template Wrapped2<unsigned long, unsigned int>;
template Wrapped2<unsigned long, unsigned char>;
template Wrapped2<unsigned long, unsigned long>;
template Wrapped6<long, int>;
template Wrapped6<long, signed char>;
template Wrapped6<int, signed char>;
template Wrapped6<unsigned long, unsigned int>;
template Wrapped6<unsigned long, unsigned char>;
template Wrapped6<unsigned int, unsigned char>;
#endif
#define PRIVATE_EXPR_TEST(e, t) BOOST_TEST( ((e), (t)) )
@ -459,6 +583,14 @@ test_main( int , char * [] )
tester<unsigned long, unsigned long>()(r);
tester<unsigned int, unsigned int>()(r);
tester<unsigned int, unsigned char>()(r);
tester_left<long, int>()(r);
tester_left<long, signed char>()(r);
tester_left<int, signed char>()(r);
tester_left<unsigned long, unsigned int>()(r);
tester_left<unsigned long, unsigned char>()(r);
tester_left<unsigned int, unsigned char>()(r);
}
cout << "Did random tester loop." << endl;
@ -653,5 +785,106 @@ test_main( int , char * [] )
cout << "Performed tests on MyShort objects.\n";
MyDoubleInt di1(1);
MyDoubleInt di2(2.);
MyDoubleInt half(0.5);
MyDoubleInt di;
MyDoubleInt tmp;
BOOST_TEST( di1.value() == 1 );
BOOST_TEST( di2.value() == 2 );
BOOST_TEST( di2.value() == 2 );
BOOST_TEST( di.value() == 0 );
cout << "Created MyDoubleInt objects.\n";
PRIVATE_EXPR_TEST( (di = di2), (di.value() == 2) );
BOOST_TEST( 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 );
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 );
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 );
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 );
PRIVATE_EXPR_TEST( (tmp=di1), ((tmp+=1) == di2) );
PRIVATE_EXPR_TEST( (tmp=di1), ((tmp+=di1) == di2) );
cout << "Performed tests on MyDoubleInt objects.\n";
MyLongInt li1(1);
MyLongInt li2(2);
MyLongInt li;
MyLongInt tmp2;
BOOST_TEST( li1.value() == 1 );
BOOST_TEST( li2.value() == 2 );
BOOST_TEST( li.value() == 0 );
cout << "Created MyLongInt objects.\n";
PRIVATE_EXPR_TEST( (li = li2), (li.value() == 2) );
BOOST_TEST( 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 );
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 );
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 );
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 );
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 );
PRIVATE_EXPR_TEST( (tmp2=li1), ((tmp2+=1) == li2) );
PRIVATE_EXPR_TEST( (tmp2=li1), ((tmp2+=li1) == li2) );
cout << "Performed tests on MyLongInt objects.\n";
return boost::exit_success;
}

177
permutation_iterator.htm Normal file
View File

@ -0,0 +1,177 @@
<!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 &lt;class IndexIterator&gt;
class permutation_iterator_policies;
template &lt;class ElementIterator, class IndexIterator&gt;
class permutation_iterator_generator;
template &lt;class ElementIterator, class IndexIterator&gt;
typename permutation_iterator_generator&lt;ElementIterator, IndexIterator&gt;::type
make_permutation_iterator(ElementIterator&amp; base, IndexIterator&amp; 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 &lt;class ElementIterator, class IndexIterator&gt;
class permutation_iterator_generator
{
public:
typedef <a href="iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a>&lt...&gt; 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 &lt;class ElementIterator, class IndexIterator &gt;
typename permutation_iterator_generator&lt;ElementIterator, IndexIterator&gt;::type
make_permutation_iterator(ElementIterator&amp; base, IndexIterator&amp; 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>

115
ref_ct_test.cpp Normal file
View File

@ -0,0 +1,115 @@
// 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/static_assert.hpp>
namespace {
template< typename T, typename U >
void ref_test(boost::reference_wrapper<U>)
{
typedef typename boost::reference_wrapper<U>::type type;
BOOST_STATIC_ASSERT((boost::is_same<U,type>::value));
BOOST_STATIC_ASSERT((boost::is_same<T,type>::value));
}
template< typename T >
void assignable_test(T x)
{
x = x;
}
template< bool R, typename T >
void is_reference_wrapper_test(T)
{
BOOST_STATIC_ASSERT(boost::is_reference_wrapper<T>::value == R);
}
template< typename R, typename Ref >
void cxx_reference_test(Ref)
{
BOOST_STATIC_ASSERT((boost::is_same<R,Ref>::value));
}
template< typename R, typename Ref >
void unwrap_reference_test(Ref)
{
typedef typename boost::unwrap_reference<Ref>::type type;
BOOST_STATIC_ASSERT((boost::is_same<R,type>::value));
}
} // namespace
int main()
{
int i = 0;
int& ri = i;
int const ci = 0;
int const& rci = ci;
// 'ref/cref' functions test
ref_test<int>(boost::ref(i));
ref_test<int>(boost::ref(ri));
ref_test<int const>(boost::ref(ci));
ref_test<int const>(boost::ref(rci));
ref_test<int const>(boost::cref(i));
ref_test<int const>(boost::cref(ri));
ref_test<int const>(boost::cref(ci));
ref_test<int const>(boost::cref(rci));
// test 'assignable' requirement
assignable_test(boost::ref(i));
assignable_test(boost::ref(ri));
assignable_test(boost::cref(i));
assignable_test(boost::cref(ci));
assignable_test(boost::cref(rci));
// 'is_reference_wrapper' test
is_reference_wrapper_test<true>(boost::ref(i));
is_reference_wrapper_test<true>(boost::ref(ri));
is_reference_wrapper_test<true>(boost::cref(i));
is_reference_wrapper_test<true>(boost::cref(ci));
is_reference_wrapper_test<true>(boost::cref(rci));
is_reference_wrapper_test<false>(i);
is_reference_wrapper_test<false, int&>(ri);
is_reference_wrapper_test<false>(ci);
is_reference_wrapper_test<false, int const&>(rci);
// ordinary references/function template arguments deduction test
cxx_reference_test<int>(i);
cxx_reference_test<int>(ri);
cxx_reference_test<int>(ci);
cxx_reference_test<int>(rci);
cxx_reference_test<int&, int&>(i);
cxx_reference_test<int&, int&>(ri);
cxx_reference_test<int const&, int const&>(i);
cxx_reference_test<int const&, int const&>(ri);
cxx_reference_test<int const&, int const&>(ci);
cxx_reference_test<int const&, int const&>(rci);
// 'unwrap_reference' test
unwrap_reference_test<int>(boost::ref(i));
unwrap_reference_test<int>(boost::ref(ri));
unwrap_reference_test<int const>(boost::cref(i));
unwrap_reference_test<int const>(boost::cref(ci));
unwrap_reference_test<int const>(boost::cref(rci));
unwrap_reference_test<int>(i);
unwrap_reference_test<int>(ri);
unwrap_reference_test<int>(ci);
unwrap_reference_test<int>(rci);
unwrap_reference_test<int&, int&>(i);
unwrap_reference_test<int&, int&>(ri);
unwrap_reference_test<int const&, int const&>(i);
unwrap_reference_test<int const&, int const&>(ri);
unwrap_reference_test<int const&, int const&>(ci);
unwrap_reference_test<int const&, int const&>(rci);
return 0;
}

74
ref_test.cpp Normal file
View File

@ -0,0 +1,74 @@
// run-time test for "boost/ref.hpp" header content
// see 'ref_ct_test.cpp' for compile-time part
#if defined(_MSC_VER) && !defined(__ICL)
# pragma warning(disable: 4786) // identifier truncated in debug info
# pragma warning(disable: 4710) // function not inlined
# pragma warning(disable: 4711) // function selected for automatic inline expansion
# pragma warning(disable: 4514) // unreferenced inline removed
#endif
#include <boost/ref.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
#define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp>
namespace {
using namespace boost;
template <class T>
struct ref_wrapper
{
// Used to verify implicit conversion
static T* get_pointer(T& x)
{
return &x;
}
static T const* get_const_pointer(T const& x)
{
return &x;
}
template <class Arg>
static T* passthru(Arg x)
{
return get_pointer(x);
}
template <class Arg>
static T const* cref_passthru(Arg x)
{
return get_const_pointer(x);
}
static void test(T x)
{
BOOST_TEST(passthru(ref(x)) == &x);
BOOST_TEST(&ref(x).get() == &x);
BOOST_TEST(cref_passthru(cref(x)) == &x);
BOOST_TEST(&cref(x).get() == &x);
}
};
} // namespace unnamed
int test_main(int, char * [])
{
ref_wrapper<int>::test(1);
ref_wrapper<int const>::test(1);
return 0;
}

View File

@ -10,23 +10,32 @@
int main(int, char*[])
{
char letters[] = "hello world!";
const int N = sizeof(letters)/sizeof(char) - 1;
char letters_[] = "hello world!";
const int N = sizeof(letters_)/sizeof(char) - 1;
#ifdef BOOST_NO_STD_ITERATOR_TRAITS
// Assume there won't be proper iterator traits for pointers. This
// is just a wrapper for char* which has the right traits.
typedef boost::iterator_adaptor<char*, boost::default_iterator_policies, char> base_iterator;
#else
typedef char* base_iterator;
#endif
base_iterator letters(letters_);
std::cout << "original sequence of letters:\t"
<< letters << std::endl;
<< 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
boost::reverse_iterator_generator<base_iterator>::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::ostream_iterator<char>(std::cout));
std::cout << std::endl;
// Use make_reverse_iterator() to print the sequence
@ -34,8 +43,8 @@ int main(int, char*[])
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));
boost::make_reverse_iterator(reverse_letters_first),
std::ostream_iterator<char>(std::cout));
std::cout << std::endl;
return 0;

View File

@ -19,6 +19,7 @@
#include <set>
#include <algorithm>
#include <iostream>
#include <iterator> // std::distance
// Note: tie() use to live in boost/utility.hpp, but
// not it is part of the more general Boost Tuple Library.
#include <boost/tuple/tuple.hpp>
@ -41,9 +42,9 @@ main(int, char*[])
for (int k = 0; k < 2; ++k) {
boost::tie(i,inserted) = s.insert(new_vals[k]);
if (!inserted)
std::cout << *i << " was already in the set." << std::endl;
std::cout << *i << " was already in the set." << std::endl;
else
std::cout << *i << " successfully inserted." << std::endl;
std::cout << *i << " successfully inserted." << std::endl;
}
}
{
@ -55,7 +56,7 @@ main(int, char*[])
boost::tie(i,end) = std::equal_range(vals, vals + 6, 4);
std::cout << "There were " << std::distance(i,end)
<< " occurrences of " << *i << "." << std::endl;
<< " occurrences of " << *i << "." << std::endl;
// Footnote: of course one would normally just use std::count()
// to get this information, but that would spoil the example :)
}

View File

@ -18,15 +18,15 @@ namespace boost {
template <class Operation>
class binder1st
: public std::unary_function<typename Operation::second_argument_type,
typename Operation::result_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) {}
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);
@ -66,8 +66,8 @@ main(int, char*[])
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, " "));
boost::make_transform_iterator(x + N, boost::bind1st(std::plus<int>(), 4)),
std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
return 0;

View File

@ -22,6 +22,7 @@
checked_array_delete()</a></li>
<li>Function templates <a href="#functions next">next() and prior()</a></li>
<li>Class <a href="#Class noncopyable">noncopyable</a></li>
<li>Function template <a href="#addressof">addressof()</a></li>
<li>Function template <a href="tie.html">tie()</a> and supporting class tied.</li>
</ul>
<h2> Function templates <a name="checked_delete">checked_delete</a>() and
@ -133,6 +134,48 @@ emphasize that it is to be used only as a base class.&nbsp; Dave Abrahams notes
concern about the effect on compiler optimization of adding (even trivial inline)
destructor declarations. He says &quot;Probably this concern is misplaced, because
noncopyable will be used mostly for classes which own resources and thus have non-trivial destruction semantics.&quot;</p>
<h2><a name="addressof">Function template addressof()</a></h2>
<p>Function <strong>addressof()</strong> returns the address of an object.</p>
<blockquote>
<pre>
template &lt;typename T&gt; inline T* addressof(T& v);
template &lt;typename T&gt; inline const T* addressof(const T& v);
template &lt;typename T&gt; inline volatile T* addressof(volatile T& v);
template &lt;typename T&gt; inline const volatile T* addressof(const volatile T& v);
</pre>
</blockquote>
<p>C++ allows programmers to replace the unary
<strong>operator&()</strong> class member used to get the address of
an object. Getting the real address of an object requires ugly
casting tricks to avoid invoking the overloaded
<strong>operator&()</strong>. Function <strong>addressof()</strong>
provides a wrapper around the necessary code to make it easy to get an
object's real address.
</p>
<p>The program <a href="addressof_test.cpp">addressof_test.cpp</a> can be
used to verify that <b>addressof()</b> works as expected.</p>
<p>Contributed by Brad King based on ideas from discussion with Doug Gregor.</p>
<h3>Example</h3>
<blockquote>
<pre>#include &lt;boost/utility.hpp&gt;
struct useless_type {};
class nonaddressable {
useless_type operator&() const;
};
void f() {
nonaddressable x;
nonaddressable* xp = boost::addressof(x);
// nonaddressable* xpe = &amp;x; /* error */
}</pre>
</blockquote>
<h2>Class templates for the Base-from-Member Idiom</h2>
<p>See <a href="base_from_member.html">separate documentation</a>.</p>
<h2>Function template tie()</h2>