forked from boostorg/utility
Compare commits
38 Commits
boost-1.27
...
svn-branch
Author | SHA1 | Date | |
---|---|---|---|
cfb38f7097 | |||
4ba6a96822 | |||
1ea4140d56 | |||
351d4ecb15 | |||
7fbf84dcc6 | |||
3ff49b272d | |||
5b52e3d418 | |||
8c0eb498d3 | |||
48a81ef7ea | |||
f7610c9b26 | |||
1755eaf019 | |||
6b8b218efb | |||
333d79b345 | |||
f0fa436fe4 | |||
13e6d78fa8 | |||
7126ea2685 | |||
a37518cb4a | |||
64b3e8c3bd | |||
339937380e | |||
6156f0d302 | |||
00560e8e17 | |||
029ff9828f | |||
ec188c7c3e | |||
0a0296a5d0 | |||
6e26a5bbe7 | |||
dc1b6246a0 | |||
15f69eaf14 | |||
4774a0d325 | |||
be78ab72c9 | |||
0bc4a1b20d | |||
c8b674d105 | |||
b421d4725a | |||
1662bb5713 | |||
ad79a21abd | |||
19645a52e6 | |||
74c3077c9a | |||
1f29191329 | |||
4b636a7680 |
46
addressof_test.cpp
Normal file
46
addressof_test.cpp
Normal 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;
|
||||
}
|
@ -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:
|
||||
|
||||
|
@ -103,7 +103,7 @@ void random_sorted_sequence(T& seq)
|
||||
sort_by_value(seq);
|
||||
}
|
||||
|
||||
# if defined(BOOST_MSVC) && !defined(__SGI_STL_PORT)
|
||||
# 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)
|
||||
|
@ -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 "optimize" 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>
|
||||
|
||||
|
@ -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);
|
||||
@ -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
|
||||
|
||||
@ -245,7 +247,7 @@ int main(int argc, char *argv[ ])
|
||||
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);
|
||||
}
|
||||
@ -397,26 +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 = 20;
|
||||
unsigned int expected_failures = 24;
|
||||
#else
|
||||
unsigned int expected_failures = 0;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
@ -35,13 +35,15 @@ int main(int, char*[])
|
||||
|
||||
std::vector<std::vector<int>::iterator> pointers;
|
||||
|
||||
// VC6 gets an internal compiler error on this
|
||||
#if !defined(BOOST_MSVC) || (BOOST_MSVC > 1200)
|
||||
// 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));
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_MSVC) || (BOOST_MSVC > 1300)
|
||||
// Use indirect iterator to print out numbers by accessing
|
||||
// them through the array of pointers.
|
||||
std::cout << "indirectly printing out the numbers from 0 to "
|
||||
|
@ -240,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>();
|
||||
|
@ -22,7 +22,7 @@ int main()
|
||||
int numbers_[] = { 0, -1, 4, -3, 5, 8, -2 };
|
||||
const int N = sizeof(numbers_)/sizeof(int);
|
||||
|
||||
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
#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;
|
||||
|
@ -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
|
||||
|
@ -44,19 +44,6 @@ template<class T> struct checked_deleter
|
||||
}
|
||||
};
|
||||
|
||||
// checked_deleter<void> is needed by shared_ptr<void>::reset(0)
|
||||
|
||||
template<> struct checked_deleter<void>
|
||||
{
|
||||
typedef void result_type;
|
||||
typedef void * argument_type;
|
||||
|
||||
void operator()(void * x)
|
||||
{
|
||||
::operator delete(x); // avoid g++ warning
|
||||
}
|
||||
};
|
||||
|
||||
template<class T> struct checked_array_deleter
|
||||
{
|
||||
typedef void result_type;
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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.
|
||||
|
@ -6,12 +6,14 @@
|
||||
# endif
|
||||
|
||||
# include <boost/config.hpp>
|
||||
# include <boost/utility/addressof.hpp>
|
||||
|
||||
//
|
||||
// ref.hpp - ref/cref, useful helper functions
|
||||
//
|
||||
// Copyright (C) 1999, 2000 Jaakko J<>rvi (jaakko.jarvi@cs.utu.fi)
|
||||
// Copyright (C) 2001 Peter Dimov
|
||||
// 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.
|
||||
@ -29,18 +31,28 @@ template<class T> class reference_wrapper
|
||||
public:
|
||||
typedef T type;
|
||||
|
||||
#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300)
|
||||
|
||||
explicit reference_wrapper(T& t): t_(&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_;
|
||||
};
|
||||
|
||||
# if defined(__BORLANDC__) && (__BORLANDC__ <= 0x551)
|
||||
# if defined(__BORLANDC__) && (__BORLANDC__ <= 0x560)
|
||||
# define BOOST_REF_CONST
|
||||
# else
|
||||
# define BOOST_REF_CONST const
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
#include <boost/checked_delete.hpp>
|
||||
#include <boost/utility/base_from_member.hpp>
|
||||
#include <boost/utility/addressof.hpp>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
31
include/boost/utility/addressof.hpp
Normal file
31
include/boost/utility/addressof.hpp
Normal 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
34
index.html
Normal 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. It is
|
||||
just a collection for components too small to be called libraries in their own
|
||||
right.</p>
|
||||
<p>But that doesn't mean there isn't useful stuff here. Take a look:</p>
|
||||
<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> </p>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
@ -51,7 +51,7 @@ int main(int, char*[])
|
||||
|
||||
// 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, ","));
|
||||
|
@ -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);
|
||||
|
@ -133,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&>
|
||||
> >();
|
||||
@ -156,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));
|
||||
@ -224,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;
|
||||
@ -232,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;
|
||||
@ -247,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
|
||||
|
||||
@ -282,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
|
||||
}
|
||||
@ -300,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;
|
||||
@ -327,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(
|
||||
@ -339,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()),
|
||||
@ -348,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));
|
||||
|
@ -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>
|
||||
|
||||
@ -182,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">
|
||||
@ -191,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 "Base": 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 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>
|
||||
@ -212,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<BaseType>::value_type</tt> <a href=
|
||||
<tt>std::iterator_traits<Base>::value_type</tt> <a href=
|
||||
"#2">[2]</a>
|
||||
|
||||
<tr>
|
||||
@ -222,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&</tt> is
|
||||
used. Otherwise
|
||||
<tt>std::iterator_traits<BaseType>::reference</tt> is used. <a href="#7">[7]</a>
|
||||
<tt>std::iterator_traits<Base>::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->()</tt>.<br>
|
||||
<b>Default:</b> If <tt>Value</tt> was supplied, then <tt>Value*</tt>,
|
||||
otherwise <tt>std::iterator_traits<BaseType>::pointer</tt>. <a href="#7">[7]</a>
|
||||
<b>Default:</b> If <tt>Value</tt> was not supplied, <tt>std::iterator_traits<Base>::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->()</code> is applied.
|
||||
Otherwise, <tt>Value*</tt>.
|
||||
|
||||
<td><code>value_type*</code> or a
|
||||
class which yields <code>value_type*</code> when
|
||||
<code>operator->()</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<BaseType>::iterator_category</tt>
|
||||
<tt>std::iterator_traits<Base>::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<BaseType>::difference_type</tt>
|
||||
<tt>std::iterator_traits<Base>::difference_type</tt>
|
||||
<td>A signed integral type
|
||||
|
||||
<tr>
|
||||
<td><tt>NamedParam</tt>
|
||||
@ -360,7 +394,7 @@ typedef iterator_adaptor<foo_iterator, foo_policies,
|
||||
|
||||
<td>increments the iterator
|
||||
|
||||
<td><tt>++p</tt>, <tt>p++</tt>
|
||||
<td><tt>++x</tt>, <tt>x++</tt>
|
||||
|
||||
<tr>
|
||||
<td nowrap><tt>p.decrement(x)</tt>
|
||||
@ -496,6 +530,15 @@ struct <a name="default_iterator_policies">default_iterator_policies</a>
|
||||
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>
|
||||
@ -513,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.
|
||||
|
||||
@ -812,6 +855,19 @@ bool operator==(const iterator_adaptor<B1,P,V1,R1,P1,C,D>&,
|
||||
// and similarly for operators !=, <, <=, >=, >
|
||||
</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>
|
||||
|
@ -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));
|
||||
};
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
namespace
|
||||
{
|
||||
class DontTreadOnMe : boost::noncopyable
|
||||
class DontTreadOnMe : private boost::noncopyable
|
||||
{
|
||||
public:
|
||||
DontTreadOnMe() { std::cout << "defanged!" << std::endl; }
|
||||
|
@ -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
|
||||
|
@ -499,7 +499,6 @@ namespace
|
||||
void operator()(boost::minstd_rand& randomizer) const
|
||||
{
|
||||
Big b1 = Big( randomizer() );
|
||||
Big b2 = Big( randomizer() );
|
||||
Small s = Small( randomizer() );
|
||||
|
||||
test_left( Wrapped6<Big, Small>(b1), s, b1, s );
|
||||
|
@ -12,7 +12,7 @@ int main(int, char*[])
|
||||
{
|
||||
char letters_[] = "hello world!";
|
||||
const int N = sizeof(letters_)/sizeof(char) - 1;
|
||||
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
#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;
|
||||
|
@ -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>
|
||||
|
43
utility.htm
43
utility.htm
@ -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. Dave Abrahams notes
|
||||
concern about the effect on compiler optimization of adding (even trivial inline)
|
||||
destructor declarations. He says "Probably this concern is misplaced, because
|
||||
noncopyable will be used mostly for classes which own resources and thus have non-trivial destruction semantics."</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 <typename T> inline T* addressof(T& v);
|
||||
template <typename T> inline const T* addressof(const T& v);
|
||||
template <typename T> inline volatile T* addressof(volatile T& v);
|
||||
template <typename T> 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 <boost/utility.hpp>
|
||||
|
||||
struct useless_type {};
|
||||
class nonaddressable {
|
||||
useless_type operator&() const;
|
||||
};
|
||||
|
||||
void f() {
|
||||
nonaddressable x;
|
||||
nonaddressable* xp = boost::addressof(x);
|
||||
// nonaddressable* xpe = &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>
|
||||
|
Reference in New Issue
Block a user