mirror of
				https://github.com/boostorg/utility.git
				synced 2025-11-04 02:11:45 +01:00 
			
		
		
		
	Compare commits
	
		
			1 Commits
		
	
	
		
			boost-1.24
			...
			boost-1.21
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					9c553546a5 | 
@@ -85,7 +85,7 @@ Once that is done we can drop Multi-Pass Input Iterator.
 | 
			
		||||
<TABLE>
 | 
			
		||||
<TR valign=top>
 | 
			
		||||
<TD nowrap>Copyright © 2000</TD><TD>
 | 
			
		||||
<a HREF="../../people/jeremy_siek.htm">Jeremy Siek</a>, Univ.of Notre Dame (<A HREF="mailto:jsiek@lsc.nd.edu">jsiek@lsc.nd.edu</A>)
 | 
			
		||||
<A HREF=http://www.boost.org/people/jeremy_siek.htm>Jeremy Siek</A>, Univ.of Notre Dame (<A HREF="mailto:jsiek@lsc.nd.edu">jsiek@lsc.nd.edu</A>)
 | 
			
		||||
</TD></TR></TABLE>
 | 
			
		||||
 | 
			
		||||
</BODY>
 | 
			
		||||
 
 | 
			
		||||
@@ -193,14 +193,14 @@ int main(int argc, char *argv[ ])
 | 
			
		||||
   int i = 2;
 | 
			
		||||
   c2(i);
 | 
			
		||||
   int* pi = &i;
 | 
			
		||||
#if (defined(BOOST_MSVC6_MEMBER_TEMPLATES) || !defined(BOOST_NO_MEMBER_TEMPLATES)) && !defined(__ICL)
 | 
			
		||||
#if defined(BOOST_MSVC6_MEMBER_TEMPLATES) || !defined(BOOST_NO_MEMBER_TEMPLATES)
 | 
			
		||||
   call_traits_checker<int*> c3;
 | 
			
		||||
   c3(pi);
 | 
			
		||||
   call_traits_checker<int&> c4;
 | 
			
		||||
   c4(i);
 | 
			
		||||
   call_traits_checker<const int&> c5;
 | 
			
		||||
   c5(i);
 | 
			
		||||
#if !defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__MWERKS__)
 | 
			
		||||
#if !defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
 | 
			
		||||
   int a[2] = {1,2};
 | 
			
		||||
   call_traits_checker<int[2]> c6;
 | 
			
		||||
   c6(a);
 | 
			
		||||
@@ -238,7 +238,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))
 | 
			
		||||
   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)
 | 
			
		||||
@@ -365,8 +365,6 @@ template struct call_traits_test<int[2], true>;
 | 
			
		||||
 | 
			
		||||
#ifdef BOOST_MSVC
 | 
			
		||||
unsigned int expected_failures = 10;
 | 
			
		||||
#elif defined(__SUNPRO_CC)
 | 
			
		||||
unsigned int expected_failures = 11;
 | 
			
		||||
#elif defined(__BORLANDC__)
 | 
			
		||||
unsigned int expected_failures = 2;
 | 
			
		||||
#elif defined(__GNUC__)
 | 
			
		||||
@@ -377,4 +375,3 @@ unsigned int expected_failures = 0;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,31 +0,0 @@
 | 
			
		||||
//  Boost checked_delete test program  ---------------------------------------//
 | 
			
		||||
 | 
			
		||||
//  (C) Copyright Beman Dawes 2001. Permission to copy, use, modify, sell
 | 
			
		||||
//  and distribute this software is granted provided this copyright
 | 
			
		||||
//  notice appears in all copies. This software is provided "as is" without
 | 
			
		||||
//  express or implied warranty, and with no claim as to its suitability for
 | 
			
		||||
//  any purpose.
 | 
			
		||||
 | 
			
		||||
//  See http://www.boost.org for most recent version including documentation.
 | 
			
		||||
 | 
			
		||||
//  Revision History
 | 
			
		||||
//  21 May 01  Initial version (Beman Dawes)
 | 
			
		||||
 | 
			
		||||
#include <boost/utility.hpp>  // for checked_delete
 | 
			
		||||
 | 
			
		||||
//  This program demonstrates compiler errors when trying to delete an
 | 
			
		||||
//  incomplete type.
 | 
			
		||||
 | 
			
		||||
namespace
 | 
			
		||||
{
 | 
			
		||||
    class Incomplete;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    Incomplete * p;
 | 
			
		||||
    boost::checked_delete(p);          // should cause compile time error
 | 
			
		||||
    Incomplete ** pa;
 | 
			
		||||
    boost::checked_array_delete(pa);   // should cause compile time error
 | 
			
		||||
    return 0;
 | 
			
		||||
}   // main
 | 
			
		||||
@@ -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 Express 2.0">
 | 
			
		||||
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
 | 
			
		||||
<title>Header </title>
 | 
			
		||||
<boost/compressed_pair.hpp>
 | 
			
		||||
</head>
 | 
			
		||||
@@ -42,8 +42,6 @@ public:
 | 
			
		||||
	explicit compressed_pair(first_param_type x);
 | 
			
		||||
	explicit compressed_pair(second_param_type y);
 | 
			
		||||
 | 
			
		||||
	compressed_pair& operator=(const compressed_pair&);
 | 
			
		||||
 | 
			
		||||
	first_reference       first();
 | 
			
		||||
	first_const_reference first() const;
 | 
			
		||||
 | 
			
		||||
@@ -64,19 +62,17 @@ constructor, and this constructor initialises both values in the
 | 
			
		||||
pair to the passed value.</p>
 | 
			
		||||
 | 
			
		||||
<p>Note that compressed_pair can not be instantiated if either of
 | 
			
		||||
the template arguments is a union type, unless there is compiler
 | 
			
		||||
support for boost::is_union, or if boost::is_union is specialised
 | 
			
		||||
for the union type.</p>
 | 
			
		||||
the template arguments is an enumerator type, unless there is
 | 
			
		||||
compiler support for boost::is_enum, or if boost::is_enum is
 | 
			
		||||
specialised for the enumerator type.</p>
 | 
			
		||||
 | 
			
		||||
<p>Finally, a word of caution for Visual C++ 6 users: if either
 | 
			
		||||
argument is an empty type, then assigning to that member will
 | 
			
		||||
produce memory corruption, unless the empty type has a "do
 | 
			
		||||
nothing" assignment operator defined. This is due to a bug
 | 
			
		||||
in the way VC6 generates implicit assignment operators.</p>
 | 
			
		||||
<p>Finally, compressed_pair requires compiler support for partial
 | 
			
		||||
specialisation of class templates - without that support
 | 
			
		||||
compressed_pair behaves just like std::pair.</p>
 | 
			
		||||
 | 
			
		||||
<hr>
 | 
			
		||||
 | 
			
		||||
<p>Revised 08 May 2001</p>
 | 
			
		||||
<p>Revised 08 March 2000</p>
 | 
			
		||||
 | 
			
		||||
<p><EFBFBD> Copyright boost.org 2000. Permission to copy, use, modify,
 | 
			
		||||
sell and distribute this document is granted provided this
 | 
			
		||||
@@ -90,8 +86,7 @@ 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>
 | 
			
		||||
</body>
 | 
			
		||||
 
 | 
			
		||||
@@ -15,8 +15,6 @@
 | 
			
		||||
 | 
			
		||||
#include <boost/compressed_pair.hpp>
 | 
			
		||||
#include <boost/type_traits/type_traits_test.hpp>
 | 
			
		||||
#define BOOST_INCLUDE_MAIN
 | 
			
		||||
#include <boost/test/test_tools.hpp>
 | 
			
		||||
 | 
			
		||||
using namespace boost;
 | 
			
		||||
 | 
			
		||||
@@ -56,346 +54,101 @@ struct non_empty2
 | 
			
		||||
   { return a.i == b.i; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#ifdef __GNUC__
 | 
			
		||||
using std::swap;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
template <class T1, class T2>
 | 
			
		||||
struct compressed_pair_tester
 | 
			
		||||
int main(int argc, char *argv[ ])
 | 
			
		||||
{
 | 
			
		||||
   // define the types we need:
 | 
			
		||||
   typedef T1                                                 first_type;
 | 
			
		||||
   typedef T2                                                 second_type;
 | 
			
		||||
   typedef typename call_traits<first_type>::param_type       first_param_type;
 | 
			
		||||
   typedef typename call_traits<second_type>::param_type      second_param_type;
 | 
			
		||||
   // define our test proc:
 | 
			
		||||
   static void test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4);
 | 
			
		||||
};
 | 
			
		||||
   compressed_pair<int, double> cp1(1, 1.3);
 | 
			
		||||
   assert(cp1.first() == 1);
 | 
			
		||||
   assert(cp1.second() == 1.3);
 | 
			
		||||
   compressed_pair<int, double> cp1b(2, 2.3);
 | 
			
		||||
   assert(cp1b.first() == 2);
 | 
			
		||||
   assert(cp1b.second() == 2.3);
 | 
			
		||||
   swap(cp1, cp1b);
 | 
			
		||||
   assert(cp1b.first() == 1);
 | 
			
		||||
   assert(cp1b.second() == 1.3);
 | 
			
		||||
   assert(cp1.first() == 2);
 | 
			
		||||
   assert(cp1.second() == 2.3);
 | 
			
		||||
   compressed_pair<non_empty1, non_empty2> cp1c(non_empty1(9));
 | 
			
		||||
   assert(cp1c.second() == non_empty2());
 | 
			
		||||
   assert(cp1c.first() == non_empty1(9));
 | 
			
		||||
   compressed_pair<non_empty1, non_empty2> cp1d(non_empty2(9));
 | 
			
		||||
   assert(cp1d.second() == non_empty2(9));
 | 
			
		||||
   assert(cp1d.first() == non_empty1());
 | 
			
		||||
 | 
			
		||||
template <class T1, class T2>
 | 
			
		||||
void compressed_pair_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4)
 | 
			
		||||
{
 | 
			
		||||
#ifndef __GNUC__
 | 
			
		||||
   // gcc 2.90 can't cope with function scope using
 | 
			
		||||
   // declarations, and generates an internal compiler error...
 | 
			
		||||
   using std::swap;
 | 
			
		||||
   compressed_pair<int, double> cp1e(cp1);
 | 
			
		||||
 | 
			
		||||
   compressed_pair<empty_UDT, int> cp2(2);
 | 
			
		||||
   assert(cp2.second() == 2);
 | 
			
		||||
   compressed_pair<int, empty_UDT> cp3(1);
 | 
			
		||||
   assert(cp3.first() ==1);
 | 
			
		||||
   compressed_pair<empty_UDT, empty_UDT> cp4;
 | 
			
		||||
   compressed_pair<empty_UDT, empty_POD_UDT> cp5;
 | 
			
		||||
   compressed_pair<int, empty_UDT> cp9(empty_UDT());
 | 
			
		||||
   compressed_pair<int, empty_UDT> cp10(1);
 | 
			
		||||
   assert(cp10.first() == 1);
 | 
			
		||||
#if defined(BOOST_MSVC6_MEMBER_TEMPLATES) || !defined(BOOST_NO_MEMBER_TEMPLATES) || !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
 | 
			
		||||
   int i = 0;
 | 
			
		||||
   compressed_pair<int&, int&> cp6(i,i);
 | 
			
		||||
   assert(cp6.first() == i);
 | 
			
		||||
   assert(cp6.second() == i);
 | 
			
		||||
   assert(&cp6.first() == &i);
 | 
			
		||||
   assert(&cp6.second() == &i);
 | 
			
		||||
   compressed_pair<int, double[2]> cp7;
 | 
			
		||||
   cp7.first();
 | 
			
		||||
   double* pd = cp7.second();
 | 
			
		||||
#endif
 | 
			
		||||
   // default construct:
 | 
			
		||||
   boost::compressed_pair<T1,T2> cp1;
 | 
			
		||||
   // first param construct:
 | 
			
		||||
   boost::compressed_pair<T1,T2> cp2(p1);
 | 
			
		||||
   cp2.second() = p2;
 | 
			
		||||
   BOOST_TEST(cp2.first() == p1);
 | 
			
		||||
   BOOST_TEST(cp2.second() == p2);
 | 
			
		||||
   // second param construct:
 | 
			
		||||
   boost::compressed_pair<T1,T2> cp3(p2);
 | 
			
		||||
   cp3.first() = p1;
 | 
			
		||||
   BOOST_TEST(cp3.second() == p2);
 | 
			
		||||
   BOOST_TEST(cp3.first() == p1);
 | 
			
		||||
   // both param construct:
 | 
			
		||||
   boost::compressed_pair<T1,T2> cp4(p1, p2);
 | 
			
		||||
   BOOST_TEST(cp4.first() == p1);
 | 
			
		||||
   BOOST_TEST(cp4.second() == p2);
 | 
			
		||||
   boost::compressed_pair<T1,T2> cp5(p3, p4);
 | 
			
		||||
   BOOST_TEST(cp5.first() == p3);
 | 
			
		||||
   BOOST_TEST(cp5.second() == p4);
 | 
			
		||||
   // check const members:
 | 
			
		||||
   const boost::compressed_pair<T1,T2>& cpr1 = cp4;
 | 
			
		||||
   BOOST_TEST(cpr1.first() == p1);
 | 
			
		||||
   BOOST_TEST(cpr1.second() == p2);
 | 
			
		||||
   soft_value_test(true, (sizeof(compressed_pair<empty_UDT, int>) < sizeof(std::pair<empty_UDT, int>)))
 | 
			
		||||
   soft_value_test(true, (sizeof(compressed_pair<int, empty_UDT>) < sizeof(std::pair<int, empty_UDT>)))
 | 
			
		||||
   soft_value_test(true, (sizeof(compressed_pair<empty_UDT, empty_UDT>) < sizeof(std::pair<empty_UDT, empty_UDT>)))
 | 
			
		||||
   soft_value_test(true, (sizeof(compressed_pair<empty_UDT, empty_POD_UDT>) < sizeof(std::pair<empty_UDT, empty_POD_UDT>)))
 | 
			
		||||
   soft_value_test(true, (sizeof(compressed_pair<empty_UDT, compressed_pair<empty_POD_UDT, int> >) < sizeof(std::pair<empty_UDT, std::pair<empty_POD_UDT, int> >)))
 | 
			
		||||
 | 
			
		||||
   // copy construct:
 | 
			
		||||
   boost::compressed_pair<T1,T2> cp6(cp4);
 | 
			
		||||
   BOOST_TEST(cp6.first() == p1);
 | 
			
		||||
   BOOST_TEST(cp6.second() == p2);
 | 
			
		||||
   // assignment:
 | 
			
		||||
   cp1 = cp4;
 | 
			
		||||
   BOOST_TEST(cp1.first() == p1);
 | 
			
		||||
   BOOST_TEST(cp1.second() == p2);
 | 
			
		||||
   cp1 = cp5;
 | 
			
		||||
   BOOST_TEST(cp1.first() == p3);
 | 
			
		||||
   BOOST_TEST(cp1.second() == p4);
 | 
			
		||||
   // swap:
 | 
			
		||||
   cp4.swap(cp5);
 | 
			
		||||
   BOOST_TEST(cp4.first() == p3);
 | 
			
		||||
   BOOST_TEST(cp4.second() == p4);
 | 
			
		||||
   BOOST_TEST(cp5.first() == p1);
 | 
			
		||||
   BOOST_TEST(cp5.second() == p2);
 | 
			
		||||
   swap(cp4,cp5);
 | 
			
		||||
   BOOST_TEST(cp4.first() == p1);
 | 
			
		||||
   BOOST_TEST(cp4.second() == p2);
 | 
			
		||||
   BOOST_TEST(cp5.first() == p3);
 | 
			
		||||
   BOOST_TEST(cp5.second() == p4);
 | 
			
		||||
   return check_result(argc, argv);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// tests for case where one or both 
 | 
			
		||||
// parameters are reference types:
 | 
			
		||||
//
 | 
			
		||||
template <class T1, class T2>
 | 
			
		||||
struct compressed_pair_reference_tester
 | 
			
		||||
{
 | 
			
		||||
   // define the types we need:
 | 
			
		||||
   typedef T1                                                 first_type;
 | 
			
		||||
   typedef T2                                                 second_type;
 | 
			
		||||
   typedef typename call_traits<first_type>::param_type       first_param_type;
 | 
			
		||||
   typedef typename call_traits<second_type>::param_type      second_param_type;
 | 
			
		||||
   // define our test proc:
 | 
			
		||||
   static void test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T1, class T2>
 | 
			
		||||
void compressed_pair_reference_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4)
 | 
			
		||||
{
 | 
			
		||||
#ifndef __GNUC__
 | 
			
		||||
   // gcc 2.90 can't cope with function scope using
 | 
			
		||||
   // declarations, and generates an internal compiler error...
 | 
			
		||||
   using std::swap;
 | 
			
		||||
// instanciate some compressed pairs:
 | 
			
		||||
#ifdef __MWERKS__
 | 
			
		||||
template class compressed_pair<int, double>;
 | 
			
		||||
template class compressed_pair<int, int>;
 | 
			
		||||
template class compressed_pair<empty_UDT, int>;
 | 
			
		||||
template class compressed_pair<int, empty_UDT>;
 | 
			
		||||
template class compressed_pair<empty_UDT, empty_UDT>;
 | 
			
		||||
template class compressed_pair<empty_UDT, empty_POD_UDT>;
 | 
			
		||||
#else
 | 
			
		||||
template class boost::compressed_pair<int, double>;
 | 
			
		||||
template class boost::compressed_pair<int, int>;
 | 
			
		||||
template class boost::compressed_pair<empty_UDT, int>;
 | 
			
		||||
template class boost::compressed_pair<int, empty_UDT>;
 | 
			
		||||
template class boost::compressed_pair<empty_UDT, empty_UDT>;
 | 
			
		||||
template class boost::compressed_pair<empty_UDT, empty_POD_UDT>;
 | 
			
		||||
#endif
 | 
			
		||||
   // both param construct:
 | 
			
		||||
   boost::compressed_pair<T1,T2> cp4(p1, p2);
 | 
			
		||||
   BOOST_TEST(cp4.first() == p1);
 | 
			
		||||
   BOOST_TEST(cp4.second() == p2);
 | 
			
		||||
   boost::compressed_pair<T1,T2> cp5(p3, p4);
 | 
			
		||||
   BOOST_TEST(cp5.first() == p3);
 | 
			
		||||
   BOOST_TEST(cp5.second() == p4);
 | 
			
		||||
   // check const members:
 | 
			
		||||
   const boost::compressed_pair<T1,T2>& cpr1 = cp4;
 | 
			
		||||
   BOOST_TEST(cpr1.first() == p1);
 | 
			
		||||
   BOOST_TEST(cpr1.second() == p2);
 | 
			
		||||
 | 
			
		||||
   // copy construct:
 | 
			
		||||
   boost::compressed_pair<T1,T2> cp6(cp4);
 | 
			
		||||
   BOOST_TEST(cp6.first() == p1);
 | 
			
		||||
   BOOST_TEST(cp6.second() == p2);
 | 
			
		||||
   // assignment:
 | 
			
		||||
   // VC6 bug:
 | 
			
		||||
   // When second() is an empty class, VC6 performs the
 | 
			
		||||
   // assignment by doing a memcpy - even though the empty
 | 
			
		||||
   // class is really a zero sized base class, the result
 | 
			
		||||
   // is that the memory of first() gets trampled over.
 | 
			
		||||
   // Similar arguments apply to the case that first() is 
 | 
			
		||||
   // an empty base class.
 | 
			
		||||
   // Strangely the problem is dependent upon the compiler
 | 
			
		||||
   // settings - some generate the problem others do not.
 | 
			
		||||
   cp4.first() = p3;
 | 
			
		||||
   cp4.second() = p4;
 | 
			
		||||
   BOOST_TEST(cp4.first() == p3);
 | 
			
		||||
   BOOST_TEST(cp4.second() == p4);
 | 
			
		||||
}
 | 
			
		||||
//
 | 
			
		||||
// supplimentary tests for case where first arg only is a reference type:
 | 
			
		||||
//
 | 
			
		||||
template <class T1, class T2>
 | 
			
		||||
struct compressed_pair_reference1_tester
 | 
			
		||||
{
 | 
			
		||||
   // define the types we need:
 | 
			
		||||
   typedef T1                                                 first_type;
 | 
			
		||||
   typedef T2                                                 second_type;
 | 
			
		||||
   typedef typename call_traits<first_type>::param_type       first_param_type;
 | 
			
		||||
   typedef typename call_traits<second_type>::param_type      second_param_type;
 | 
			
		||||
   // define our test proc:
 | 
			
		||||
   static void test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T1, class T2>
 | 
			
		||||
void compressed_pair_reference1_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4)
 | 
			
		||||
{
 | 
			
		||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 | 
			
		||||
   // first param construct:
 | 
			
		||||
   boost::compressed_pair<T1,T2> cp2(p1);
 | 
			
		||||
   cp2.second() = p2;
 | 
			
		||||
   BOOST_TEST(cp2.first() == p1);
 | 
			
		||||
   BOOST_TEST(cp2.second() == p2);
 | 
			
		||||
#ifndef __MWERKS__
 | 
			
		||||
//
 | 
			
		||||
// now some for which only a few specific members can be instantiated,
 | 
			
		||||
// first references:
 | 
			
		||||
template double& compressed_pair<double, int&>::first();
 | 
			
		||||
template int& compressed_pair<double, int&>::second();
 | 
			
		||||
#if !(defined(__GNUC__) && (__GNUC__ == 2) && (__GNUC_MINOR__ < 95))
 | 
			
		||||
template compressed_pair<double, int&>::compressed_pair(int&);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
template compressed_pair<double, int&>::compressed_pair(call_traits<double>::param_type,int&);
 | 
			
		||||
//
 | 
			
		||||
// supplimentary tests for case where second arg only is a reference type:
 | 
			
		||||
//
 | 
			
		||||
template <class T1, class T2>
 | 
			
		||||
struct compressed_pair_reference2_tester
 | 
			
		||||
{
 | 
			
		||||
   // define the types we need:
 | 
			
		||||
   typedef T1                                                 first_type;
 | 
			
		||||
   typedef T2                                                 second_type;
 | 
			
		||||
   typedef typename call_traits<first_type>::param_type       first_param_type;
 | 
			
		||||
   typedef typename call_traits<second_type>::param_type      second_param_type;
 | 
			
		||||
   // define our test proc:
 | 
			
		||||
   static void test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T1, class T2>
 | 
			
		||||
void compressed_pair_reference2_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4)
 | 
			
		||||
{
 | 
			
		||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 | 
			
		||||
   // second param construct:
 | 
			
		||||
   boost::compressed_pair<T1,T2> cp3(p2);
 | 
			
		||||
   cp3.first() = p1;
 | 
			
		||||
   BOOST_TEST(cp3.second() == p2);
 | 
			
		||||
   BOOST_TEST(cp3.first() == p1);
 | 
			
		||||
// and then arrays:
 | 
			
		||||
#ifndef __BORLANDC__
 | 
			
		||||
template call_traits<int[2]>::reference compressed_pair<double, int[2]>::second();
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// tests for where one or the other parameter is an array:
 | 
			
		||||
//
 | 
			
		||||
template <class T1, class T2>
 | 
			
		||||
struct compressed_pair_array1_tester
 | 
			
		||||
{
 | 
			
		||||
   // define the types we need:
 | 
			
		||||
   typedef T1                                                 first_type;
 | 
			
		||||
   typedef T2                                                 second_type;
 | 
			
		||||
   typedef typename call_traits<first_type>::param_type       first_param_type;
 | 
			
		||||
   typedef typename call_traits<second_type>::param_type      second_param_type;
 | 
			
		||||
   // define our test proc:
 | 
			
		||||
   static void test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T1, class T2>
 | 
			
		||||
void compressed_pair_array1_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4)
 | 
			
		||||
{
 | 
			
		||||
  // default construct:
 | 
			
		||||
   boost::compressed_pair<T1,T2> cp1;
 | 
			
		||||
   // second param construct:
 | 
			
		||||
   boost::compressed_pair<T1,T2> cp3(p2);
 | 
			
		||||
   cp3.first()[0] = p1[0];
 | 
			
		||||
   BOOST_TEST(cp3.second() == p2);
 | 
			
		||||
   BOOST_TEST(cp3.first()[0] == p1[0]);
 | 
			
		||||
   // check const members:
 | 
			
		||||
   const boost::compressed_pair<T1,T2>& cpr1 = cp3;
 | 
			
		||||
   BOOST_TEST(cpr1.first()[0] == p1[0]);
 | 
			
		||||
   BOOST_TEST(cpr1.second() == p2);
 | 
			
		||||
 | 
			
		||||
   BOOST_TEST(sizeof(T1) == sizeof(cp1.first()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class T1, class T2>
 | 
			
		||||
struct compressed_pair_array2_tester
 | 
			
		||||
{
 | 
			
		||||
   // define the types we need:
 | 
			
		||||
   typedef T1                                                 first_type;
 | 
			
		||||
   typedef T2                                                 second_type;
 | 
			
		||||
   typedef typename call_traits<first_type>::param_type       first_param_type;
 | 
			
		||||
   typedef typename call_traits<second_type>::param_type      second_param_type;
 | 
			
		||||
   // define our test proc:
 | 
			
		||||
   static void test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T1, class T2>
 | 
			
		||||
void compressed_pair_array2_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4)
 | 
			
		||||
{
 | 
			
		||||
   // default construct:
 | 
			
		||||
   boost::compressed_pair<T1,T2> cp1;
 | 
			
		||||
   // first param construct:
 | 
			
		||||
   boost::compressed_pair<T1,T2> cp2(p1);
 | 
			
		||||
   cp2.second()[0] = p2[0];
 | 
			
		||||
   BOOST_TEST(cp2.first() == p1);
 | 
			
		||||
   BOOST_TEST(cp2.second()[0] == p2[0]);
 | 
			
		||||
   // check const members:
 | 
			
		||||
   const boost::compressed_pair<T1,T2>& cpr1 = cp2;
 | 
			
		||||
   BOOST_TEST(cpr1.first() == p1);
 | 
			
		||||
   BOOST_TEST(cpr1.second()[0] == p2[0]);
 | 
			
		||||
 | 
			
		||||
   BOOST_TEST(sizeof(T2) == sizeof(cp1.second()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class T1, class T2>
 | 
			
		||||
struct compressed_pair_array_tester
 | 
			
		||||
{
 | 
			
		||||
   // define the types we need:
 | 
			
		||||
   typedef T1                                                 first_type;
 | 
			
		||||
   typedef T2                                                 second_type;
 | 
			
		||||
   typedef typename call_traits<first_type>::param_type       first_param_type;
 | 
			
		||||
   typedef typename call_traits<second_type>::param_type      second_param_type;
 | 
			
		||||
   // define our test proc:
 | 
			
		||||
   static void test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T1, class T2>
 | 
			
		||||
void compressed_pair_array_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4)
 | 
			
		||||
{
 | 
			
		||||
   // default construct:
 | 
			
		||||
   boost::compressed_pair<T1,T2> cp1;
 | 
			
		||||
   cp1.first()[0] = p1[0];
 | 
			
		||||
   cp1.second()[0] = p2[0];
 | 
			
		||||
   BOOST_TEST(cp1.first()[0] == p1[0]);
 | 
			
		||||
   BOOST_TEST(cp1.second()[0] == p2[0]);
 | 
			
		||||
   // check const members:
 | 
			
		||||
   const boost::compressed_pair<T1,T2>& cpr1 = cp1;
 | 
			
		||||
   BOOST_TEST(cpr1.first()[0] == p1[0]);
 | 
			
		||||
   BOOST_TEST(cpr1.second()[0] == p2[0]);
 | 
			
		||||
 | 
			
		||||
   BOOST_TEST(sizeof(T1) == sizeof(cp1.first()));
 | 
			
		||||
   BOOST_TEST(sizeof(T2) == sizeof(cp1.second()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int test_main(int argc, char *argv[ ])
 | 
			
		||||
{
 | 
			
		||||
   // declare some variables to pass to the tester:
 | 
			
		||||
   non_empty1 ne1(2);
 | 
			
		||||
   non_empty1 ne2(3);
 | 
			
		||||
   non_empty2 ne3(4);
 | 
			
		||||
   non_empty2 ne4(5);
 | 
			
		||||
   empty_POD_UDT  e1;
 | 
			
		||||
   empty_UDT      e2;
 | 
			
		||||
 | 
			
		||||
   // T1 != T2, both non-empty
 | 
			
		||||
   compressed_pair_tester<non_empty1,non_empty2>::test(ne1, ne3, ne2, ne4);
 | 
			
		||||
   // T1 != T2, T2 empty
 | 
			
		||||
   compressed_pair_tester<non_empty1,empty_POD_UDT>::test(ne1, e1, ne2, e1);
 | 
			
		||||
   // T1 != T2, T1 empty
 | 
			
		||||
   compressed_pair_tester<empty_POD_UDT,non_empty2>::test(e1, ne3, e1, ne4);
 | 
			
		||||
   // T1 != T2, both empty
 | 
			
		||||
   compressed_pair_tester<empty_POD_UDT,empty_UDT>::test(e1, e2, e1, e2);
 | 
			
		||||
   // T1 == T2, both non-empty
 | 
			
		||||
   compressed_pair_tester<non_empty1,non_empty1>::test(ne1, ne1, ne2, ne2);
 | 
			
		||||
   // T1 == T2, both empty
 | 
			
		||||
   compressed_pair_tester<empty_UDT,empty_UDT>::test(e2, e2, e2, e2);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
   // test references:
 | 
			
		||||
 | 
			
		||||
   // T1 != T2, both non-empty
 | 
			
		||||
   compressed_pair_reference_tester<non_empty1&,non_empty2>::test(ne1, ne3, ne2, ne4);
 | 
			
		||||
   compressed_pair_reference_tester<non_empty1,non_empty2&>::test(ne1, ne3, ne2, ne4);
 | 
			
		||||
   compressed_pair_reference1_tester<non_empty1&,non_empty2>::test(ne1, ne3, ne2, ne4);
 | 
			
		||||
   compressed_pair_reference2_tester<non_empty1,non_empty2&>::test(ne1, ne3, ne2, ne4);
 | 
			
		||||
   // T1 != T2, T2 empty
 | 
			
		||||
   compressed_pair_reference_tester<non_empty1&,empty_POD_UDT>::test(ne1, e1, ne2, e1);
 | 
			
		||||
   compressed_pair_reference1_tester<non_empty1&,empty_POD_UDT>::test(ne1, e1, ne2, e1);
 | 
			
		||||
   // T1 != T2, T1 empty
 | 
			
		||||
   compressed_pair_reference_tester<empty_POD_UDT,non_empty2&>::test(e1, ne3, e1, ne4);
 | 
			
		||||
   compressed_pair_reference2_tester<empty_POD_UDT,non_empty2&>::test(e1, ne3, e1, ne4);
 | 
			
		||||
   // T1 == T2, both non-empty
 | 
			
		||||
   compressed_pair_reference_tester<non_empty1&,non_empty1&>::test(ne1, ne1, ne2, ne2);
 | 
			
		||||
 | 
			
		||||
   // tests arrays:
 | 
			
		||||
   non_empty1 nea1[2];
 | 
			
		||||
   non_empty1 nea2[2];
 | 
			
		||||
   non_empty2 nea3[2];
 | 
			
		||||
   non_empty2 nea4[2];
 | 
			
		||||
   nea1[0] = non_empty1(5);
 | 
			
		||||
   nea2[0] = non_empty1(6);
 | 
			
		||||
   nea3[0] = non_empty2(7);
 | 
			
		||||
   nea4[0] = non_empty2(8);
 | 
			
		||||
   
 | 
			
		||||
   // T1 != T2, both non-empty
 | 
			
		||||
   compressed_pair_array1_tester<non_empty1[2],non_empty2>::test(nea1, ne3, nea2, ne4);
 | 
			
		||||
   compressed_pair_array2_tester<non_empty1,non_empty2[2]>::test(ne1, nea3, ne2, nea4);
 | 
			
		||||
   compressed_pair_array_tester<non_empty1[2],non_empty2[2]>::test(nea1, nea3, nea2, nea4);
 | 
			
		||||
   // T1 != T2, T2 empty
 | 
			
		||||
   compressed_pair_array1_tester<non_empty1[2],empty_POD_UDT>::test(nea1, e1, nea2, e1);
 | 
			
		||||
   // T1 != T2, T1 empty
 | 
			
		||||
   compressed_pair_array2_tester<empty_POD_UDT,non_empty2[2]>::test(e1, nea3, e1, nea4);
 | 
			
		||||
   // T1 == T2, both non-empty
 | 
			
		||||
   compressed_pair_array_tester<non_empty1[2],non_empty1[2]>::test(nea1, nea1, nea2, nea2);
 | 
			
		||||
   return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template call_traits<double>::reference compressed_pair<double, int[2]>::first();
 | 
			
		||||
#if !(defined(__GNUC__) && (__GNUC__ == 2) && (__GNUC_MINOR__ < 95))
 | 
			
		||||
template compressed_pair<double, int[2]>::compressed_pair(call_traits<double>::param_type);
 | 
			
		||||
#endif
 | 
			
		||||
template compressed_pair<double, int[2]>::compressed_pair();
 | 
			
		||||
#endif // __MWERKS__
 | 
			
		||||
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 | 
			
		||||
 | 
			
		||||
unsigned int expected_failures = 0;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -308,7 +308,7 @@ implementation, the <tt>difference_type</tt> for any variable-length signed
 | 
			
		||||
integer type <tt>T</tt> is <tt>T</tt> itself.
 | 
			
		||||
 | 
			
		||||
<hr>
 | 
			
		||||
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->17 Aug 2001<!--webbot bot="Timestamp" endspan i-checksum="14763" --></p>
 | 
			
		||||
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->08 Mar 2001<!--webbot bot="Timestamp" endspan i-checksum="14892" --></p>
 | 
			
		||||
<p><EFBFBD> Copyright Jeremy Siek 2000. Permission to copy, use,
 | 
			
		||||
modify, sell and distribute this document is granted provided this copyright
 | 
			
		||||
notice appears in all copies. This document is provided "as is"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,23 +1,20 @@
 | 
			
		||||
//  Boost operators.hpp header file  ----------------------------------------//
 | 
			
		||||
 | 
			
		||||
//  (C) Copyright David Abrahams, Jeremy Siek, and Daryle Walker 1999-2001.
 | 
			
		||||
//  Permission to copy, use, modify, sell and distribute this software is
 | 
			
		||||
//  granted provided this copyright notice appears in all copies.  This
 | 
			
		||||
//  software is provided "as is" without express or implied warranty, and
 | 
			
		||||
//  with no claim as to its suitability for any purpose.
 | 
			
		||||
//  (C) Copyright David Abrahams 1999. Permission to copy, use,
 | 
			
		||||
//  modify, sell and distribute this software is granted provided this
 | 
			
		||||
//  copyright notice appears in all copies. This software is provided
 | 
			
		||||
//  "as is" without express or implied warranty, and with no claim as
 | 
			
		||||
//  to its suitability for any purpose.
 | 
			
		||||
 | 
			
		||||
//  (C) Copyright Jeremy Siek 1999. Permission to copy, use, modify,
 | 
			
		||||
//  sell and distribute this software is granted provided this
 | 
			
		||||
//  copyright notice appears in all copies. This software is provided
 | 
			
		||||
//  "as is" without express or implied warranty, and with no claim as
 | 
			
		||||
//  to its suitability for any purpose.
 | 
			
		||||
 | 
			
		||||
//  See http://www.boost.org for most recent version including documentation.
 | 
			
		||||
 | 
			
		||||
//  Revision History
 | 
			
		||||
//  25 Jun 01 output_iterator_helper changes: removed default template 
 | 
			
		||||
//            parameters, added support for self-proxying, additional 
 | 
			
		||||
//            documentation and tests (Aleksey Gurtovoy)
 | 
			
		||||
//  29 May 01 Added operator classes for << and >>.  Added input and output
 | 
			
		||||
//            iterator helper classes.  Added classes to connect equality and
 | 
			
		||||
//            relational operators.  Added classes for groups of related
 | 
			
		||||
//            operators.  Reimplemented example operator and iterator helper
 | 
			
		||||
//            classes in terms of the new groups.  (Daryle Walker, with help
 | 
			
		||||
//            from Alexy Gurtovoy)
 | 
			
		||||
//  11 Feb 01 Fixed bugs in the iterator helpers which prevented explicitly
 | 
			
		||||
//            supplied arguments from actually being used (Dave Abrahams)
 | 
			
		||||
//  04 Jul 00 Fixed NO_OPERATORS_IN_NAMESPACE bugs, major cleanup and
 | 
			
		||||
@@ -285,190 +282,12 @@ struct indexable : B
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//  More operator classes (contributed by Daryle Walker) --------------------//
 | 
			
		||||
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct left_shiftable2 : B
 | 
			
		||||
{
 | 
			
		||||
     friend T operator<<(T x, const U& y) { return x <<= y; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct left_shiftable1 : B
 | 
			
		||||
{
 | 
			
		||||
     friend T operator<<(T x, const T& y) { return x <<= y; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct right_shiftable2 : B
 | 
			
		||||
{
 | 
			
		||||
     friend T operator>>(T x, const U& y) { return x >>= y; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct right_shiftable1 : B
 | 
			
		||||
{
 | 
			
		||||
     friend T operator>>(T x, const T& y) { return x >>= y; }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct equivalent2 : B
 | 
			
		||||
{
 | 
			
		||||
  friend bool operator==(const T& x, const U& y)
 | 
			
		||||
  {
 | 
			
		||||
    return !(x < y) && !(x > y);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct equivalent1 : B
 | 
			
		||||
{
 | 
			
		||||
  friend bool operator==(const T&x, const T&y)
 | 
			
		||||
  {
 | 
			
		||||
    return !(x < y) && !(y < x);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct partially_ordered2 : B
 | 
			
		||||
{
 | 
			
		||||
  friend bool operator<=(const T& x, const U& y)
 | 
			
		||||
    { return (x < y) || (x == y); }
 | 
			
		||||
  friend bool operator>=(const T& x, const U& y)
 | 
			
		||||
    { return (x > y) || (x == y); }
 | 
			
		||||
  friend bool operator>(const U& x, const T& y)
 | 
			
		||||
    { return y < x; }
 | 
			
		||||
  friend bool operator<(const U& x, const T& y)
 | 
			
		||||
    { return y > x; }
 | 
			
		||||
  friend bool operator<=(const U& x, const T& y)
 | 
			
		||||
    { return (y > x) || (y == x); }
 | 
			
		||||
  friend bool operator>=(const U& x, const T& y)
 | 
			
		||||
    { return (y < x) || (y == x); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct partially_ordered1 : B
 | 
			
		||||
{
 | 
			
		||||
  friend bool operator>(const T& x, const T& y)
 | 
			
		||||
    { return y < x; }
 | 
			
		||||
  friend bool operator<=(const T& x, const T& y)
 | 
			
		||||
    { return (x < y) || (x == y); }
 | 
			
		||||
  friend bool operator>=(const T& x, const T& y)
 | 
			
		||||
    { return (y < x) || (x == y); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//  Combined operator classes (contributed by Daryle Walker) ----------------//
 | 
			
		||||
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct totally_ordered2
 | 
			
		||||
    : less_than_comparable2<T, U
 | 
			
		||||
    , equality_comparable2<T, U, B
 | 
			
		||||
      > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct totally_ordered1
 | 
			
		||||
    : less_than_comparable1<T
 | 
			
		||||
    , equality_comparable1<T, B
 | 
			
		||||
      > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct additive2
 | 
			
		||||
    : addable2<T, U
 | 
			
		||||
    , subtractable2<T, U, B
 | 
			
		||||
      > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct additive1
 | 
			
		||||
    : addable1<T
 | 
			
		||||
    , subtractable1<T, B
 | 
			
		||||
      > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct multiplicative2
 | 
			
		||||
    : multipliable2<T, U
 | 
			
		||||
    , dividable2<T, U, B
 | 
			
		||||
      > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct multiplicative1
 | 
			
		||||
    : multipliable1<T
 | 
			
		||||
    , dividable1<T, B
 | 
			
		||||
      > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct integer_multiplicative2
 | 
			
		||||
    : multiplicative2<T, U
 | 
			
		||||
    , modable2<T, U, B
 | 
			
		||||
      > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct integer_multiplicative1
 | 
			
		||||
    : multiplicative1<T
 | 
			
		||||
    , modable1<T, B
 | 
			
		||||
      > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct arithmetic2
 | 
			
		||||
    : additive2<T, U
 | 
			
		||||
    , multiplicative2<T, U, B
 | 
			
		||||
      > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct arithmetic1
 | 
			
		||||
    : additive1<T
 | 
			
		||||
    , multiplicative1<T, B
 | 
			
		||||
      > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct integer_arithmetic2
 | 
			
		||||
    : additive2<T, U
 | 
			
		||||
    , integer_multiplicative2<T, U, B
 | 
			
		||||
      > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct integer_arithmetic1
 | 
			
		||||
    : additive1<T
 | 
			
		||||
    , integer_multiplicative1<T, B
 | 
			
		||||
      > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct bitwise2
 | 
			
		||||
    : xorable2<T, U
 | 
			
		||||
    , andable2<T, U
 | 
			
		||||
    , orable2<T, U, B
 | 
			
		||||
      > > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct bitwise1
 | 
			
		||||
    : xorable1<T
 | 
			
		||||
    , andable1<T
 | 
			
		||||
    , orable1<T, B
 | 
			
		||||
      > > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct unit_steppable
 | 
			
		||||
    : incrementable<T
 | 
			
		||||
    , decrementable<T, B
 | 
			
		||||
      > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class U, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct shiftable2
 | 
			
		||||
    : left_shiftable2<T, U
 | 
			
		||||
    , right_shiftable2<T, U, B
 | 
			
		||||
      > > {};
 | 
			
		||||
 | 
			
		||||
template <class T, class B = ::boost::detail::empty_base>
 | 
			
		||||
struct shiftable1
 | 
			
		||||
    : left_shiftable1<T
 | 
			
		||||
    , right_shiftable1<T, 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_TEMPLATE2 -
 | 
			
		||||
//
 | 
			
		||||
// 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
 | 
			
		||||
@@ -476,31 +295,12 @@ struct shiftable1
 | 
			
		||||
// two-argument forms. Note that these macros expect to be invoked from within
 | 
			
		||||
// boost.
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
 | 
			
		||||
#if defined(BOOST_NO_OPERATORS_IN_NAMESPACE)
 | 
			
		||||
 | 
			
		||||
  // The template is already in boost so we have nothing to do.
 | 
			
		||||
# define BOOST_IMPORT_TEMPLATE3(template_name)
 | 
			
		||||
# define BOOST_IMPORT_TEMPLATE2(template_name)
 | 
			
		||||
# define BOOST_IMPORT_TEMPLATE1(template_name)
 | 
			
		||||
 | 
			
		||||
#else // BOOST_NO_OPERATORS_IN_NAMESPACE
 | 
			
		||||
 | 
			
		||||
#  ifndef BOOST_NO_USING_TEMPLATE
 | 
			
		||||
 | 
			
		||||
     // Bring the names in with a using-declaration
 | 
			
		||||
     // to avoid stressing the compiler.
 | 
			
		||||
#    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;
 | 
			
		||||
 | 
			
		||||
#  else
 | 
			
		||||
 | 
			
		||||
     // 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_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> {};
 | 
			
		||||
#  if defined(BOOST_NO_USING_TEMPLATE)
 | 
			
		||||
 | 
			
		||||
     // 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_TEMPLATE2(template_name)                              \
 | 
			
		||||
     template <class T, class U, class B = ::boost::detail::empty_base>        \
 | 
			
		||||
     struct template_name : ::template_name<T, U, B> {};
 | 
			
		||||
@@ -509,8 +309,21 @@ struct shiftable1
 | 
			
		||||
     template <class T, class B = ::boost::detail::empty_base>                 \
 | 
			
		||||
     struct template_name : ::template_name<T, B> {};
 | 
			
		||||
 | 
			
		||||
#  else
 | 
			
		||||
 | 
			
		||||
     // Otherwise, bring the names in with a using-declaration to avoid
 | 
			
		||||
     // stressing the compiler
 | 
			
		||||
#    define BOOST_IMPORT_TEMPLATE2(template_name) using ::template_name;
 | 
			
		||||
#    define BOOST_IMPORT_TEMPLATE1(template_name) using ::template_name;
 | 
			
		||||
 | 
			
		||||
#  endif // BOOST_NO_USING_TEMPLATE
 | 
			
		||||
 | 
			
		||||
#else // !BOOST_NO_OPERATORS_IN_NAMESPACE
 | 
			
		||||
 | 
			
		||||
  // The template is already in boost so we have nothing to do.
 | 
			
		||||
# define BOOST_IMPORT_TEMPLATE2(template_name)
 | 
			
		||||
# define BOOST_IMPORT_TEMPLATE1(template_name)
 | 
			
		||||
 | 
			
		||||
#endif // BOOST_NO_OPERATORS_IN_NAMESPACE
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
@@ -519,7 +332,7 @@ struct shiftable1
 | 
			
		||||
// the xxxx, xxxx1, and xxxx2 templates, importing them into boost:: as
 | 
			
		||||
// neccessary.
 | 
			
		||||
//
 | 
			
		||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 | 
			
		||||
#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
 | 
			
		||||
 | 
			
		||||
// is_chained_base<> - a traits class used to distinguish whether an operator
 | 
			
		||||
// template argument is being used for base class chaining, or is specifying a
 | 
			
		||||
@@ -542,15 +355,6 @@ template<class T> struct is_chained_base {
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 | 
			
		||||
// 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)                     \
 | 
			
		||||
  BOOST_IMPORT_TEMPLATE3(template_name3)                              \
 | 
			
		||||
  template<class T, class U, class V, class B>                        \
 | 
			
		||||
  struct is_chained_base< ::boost::template_name3<T, U, V, B> > {     \
 | 
			
		||||
    typedef ::boost::detail::true_t value;                            \
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
// Import a 2-type-argument operator template into boost (if neccessary) and
 | 
			
		||||
// provide a specialization of 'is_chained_base<>' for it.
 | 
			
		||||
# define BOOST_OPERATOR_TEMPLATE2(template_name2)                  \
 | 
			
		||||
@@ -610,8 +414,6 @@ BOOST_OPERATOR_TEMPLATE1(template_name##1)
 | 
			
		||||
 | 
			
		||||
#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 | 
			
		||||
 | 
			
		||||
#  define BOOST_OPERATOR_TEMPLATE3(template_name3) \
 | 
			
		||||
        BOOST_IMPORT_TEMPLATE3(template_name3)
 | 
			
		||||
#  define BOOST_OPERATOR_TEMPLATE2(template_name2) \
 | 
			
		||||
        BOOST_IMPORT_TEMPLATE2(template_name2)
 | 
			
		||||
#  define BOOST_OPERATOR_TEMPLATE1(template_name1) \
 | 
			
		||||
@@ -640,41 +442,47 @@ BOOST_OPERATOR_TEMPLATE(orable)
 | 
			
		||||
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE1(incrementable)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE1(decrementable)
 | 
			
		||||
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE2(dereferenceable)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE3(indexable)
 | 
			
		||||
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE(left_shiftable)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE(right_shiftable)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE(equivalent)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE(partially_ordered)
 | 
			
		||||
// indexable doesn't follow the patterns above (it has 4 template arguments), so
 | 
			
		||||
// we just write out the compiler hacks explicitly.
 | 
			
		||||
#ifdef BOOST_NO_OPERATORS_IN_NAMESPACE
 | 
			
		||||
# ifdef BOOST_NO_USING_TEMPLATE
 | 
			
		||||
   template <class T, class I, class R, class B = ::boost::detail::empty_base>
 | 
			
		||||
   struct indexable : ::indexable<T,I,R,B> {};
 | 
			
		||||
# else
 | 
			
		||||
   using ::indexable;
 | 
			
		||||
# endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE(totally_ordered)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE(additive)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE(multiplicative)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE(integer_multiplicative)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE(arithmetic)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE(integer_arithmetic)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE(bitwise)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE1(unit_steppable)
 | 
			
		||||
BOOST_OPERATOR_TEMPLATE(shiftable)
 | 
			
		||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 | 
			
		||||
template <class T, class I, class R, class B>
 | 
			
		||||
struct is_chained_base< ::boost::indexable<T, I, R, B> > {
 | 
			
		||||
  typedef ::boost::detail::true_t operator_template_type;
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#undef BOOST_OPERATOR_TEMPLATE
 | 
			
		||||
#undef BOOST_OPERATOR_TEMPLATE3
 | 
			
		||||
#undef BOOST_OPERATOR_TEMPLATE2
 | 
			
		||||
#undef BOOST_OPERATOR_TEMPLATE1
 | 
			
		||||
#undef BOOST_IMPORT_TEMPLATE1
 | 
			
		||||
#undef BOOST_IMPORT_TEMPLATE2
 | 
			
		||||
#undef BOOST_IMPORT_TEMPLATE3
 | 
			
		||||
 | 
			
		||||
// The following 'operators' classes can only be used portably if the derived class
 | 
			
		||||
// declares ALL of the required member operators.
 | 
			
		||||
template <class T, class U>
 | 
			
		||||
struct operators2
 | 
			
		||||
    : totally_ordered2<T,U
 | 
			
		||||
    , integer_arithmetic2<T,U
 | 
			
		||||
    , bitwise2<T,U
 | 
			
		||||
      > > > {};
 | 
			
		||||
    : less_than_comparable2<T,U
 | 
			
		||||
    , equality_comparable2<T,U
 | 
			
		||||
    , addable2<T,U
 | 
			
		||||
    , subtractable2<T,U
 | 
			
		||||
    , multipliable2<T,U
 | 
			
		||||
    , dividable2<T,U
 | 
			
		||||
    , modable2<T,U
 | 
			
		||||
    , orable2<T,U
 | 
			
		||||
    , andable2<T,U
 | 
			
		||||
    , xorable2<T,U
 | 
			
		||||
      > > > > > > > > > > {};
 | 
			
		||||
 | 
			
		||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 | 
			
		||||
template <class T, class U = T>
 | 
			
		||||
@@ -684,47 +492,31 @@ template <class T> struct operators<T, T>
 | 
			
		||||
#else
 | 
			
		||||
template <class T> struct operators
 | 
			
		||||
#endif
 | 
			
		||||
    : totally_ordered<T
 | 
			
		||||
    , integer_arithmetic<T
 | 
			
		||||
    , bitwise<T
 | 
			
		||||
    , unit_steppable<T
 | 
			
		||||
      > > > > {};
 | 
			
		||||
    : less_than_comparable<T
 | 
			
		||||
    , equality_comparable<T
 | 
			
		||||
    , addable<T
 | 
			
		||||
    , subtractable<T
 | 
			
		||||
    , multipliable<T
 | 
			
		||||
    , dividable<T
 | 
			
		||||
    , modable<T
 | 
			
		||||
    , orable<T
 | 
			
		||||
    , andable<T
 | 
			
		||||
    , xorable<T
 | 
			
		||||
    , incrementable<T
 | 
			
		||||
    , decrementable<T
 | 
			
		||||
      > > > > > > > > > > > > {};
 | 
			
		||||
 | 
			
		||||
//  Iterator helper classes (contributed by Jeremy Siek) -------------------//
 | 
			
		||||
//  (Input and output iterator helpers contributed by Daryle Walker) -------//
 | 
			
		||||
//  (Changed to use combined operator classes by Daryle Walker) ------------//
 | 
			
		||||
template <class T,
 | 
			
		||||
          class V,
 | 
			
		||||
          class D = std::ptrdiff_t,
 | 
			
		||||
          class P = V const *,
 | 
			
		||||
          class R = V const &>
 | 
			
		||||
struct input_iterator_helper
 | 
			
		||||
  : equality_comparable1<T
 | 
			
		||||
  , incrementable<T
 | 
			
		||||
  , dereferenceable<T, P
 | 
			
		||||
  , boost::iterator<std::input_iterator_tag, V, D, P, R
 | 
			
		||||
    > > > > {};
 | 
			
		||||
 | 
			
		||||
template<class Derived>
 | 
			
		||||
struct output_iterator_helper
 | 
			
		||||
  : boost::incrementable<Derived
 | 
			
		||||
  , boost::iterator<std::output_iterator_tag, void, void, void, void
 | 
			
		||||
  > >
 | 
			
		||||
{
 | 
			
		||||
  Derived& operator*()  { return static_cast<Derived&>(*this); }
 | 
			
		||||
  Derived& operator++() { return static_cast<Derived&>(*this); }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <class T,
 | 
			
		||||
          class V,
 | 
			
		||||
          class D = std::ptrdiff_t,
 | 
			
		||||
          class P = V*,
 | 
			
		||||
          class R = V&>
 | 
			
		||||
struct forward_iterator_helper
 | 
			
		||||
  : equality_comparable1<T
 | 
			
		||||
  : equality_comparable<T
 | 
			
		||||
  , incrementable<T
 | 
			
		||||
  , dereferenceable<T, P
 | 
			
		||||
  , boost::iterator<std::forward_iterator_tag, V, D, P, R
 | 
			
		||||
  , dereferenceable<T,P
 | 
			
		||||
  , boost::iterator<std::forward_iterator_tag,V,D,P,R
 | 
			
		||||
    > > > > {};
 | 
			
		||||
 | 
			
		||||
template <class T,
 | 
			
		||||
@@ -733,11 +525,12 @@ template <class T,
 | 
			
		||||
          class P = V*,
 | 
			
		||||
          class R = V&>
 | 
			
		||||
struct bidirectional_iterator_helper
 | 
			
		||||
  : equality_comparable1<T
 | 
			
		||||
  , unit_steppable<T
 | 
			
		||||
  , dereferenceable<T, P
 | 
			
		||||
  , boost::iterator<std::bidirectional_iterator_tag, V, D, P, R
 | 
			
		||||
    > > > > {};
 | 
			
		||||
  : equality_comparable<T
 | 
			
		||||
  , incrementable<T
 | 
			
		||||
  , decrementable<T
 | 
			
		||||
  , dereferenceable<T,P
 | 
			
		||||
  , boost::iterator<std::bidirectional_iterator_tag,V,D,P,R
 | 
			
		||||
    > > > > > {};
 | 
			
		||||
 | 
			
		||||
template <class T,
 | 
			
		||||
          class V, 
 | 
			
		||||
@@ -745,17 +538,22 @@ 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
 | 
			
		||||
  , boost::iterator<std::random_access_iterator_tag, V, D, P, R
 | 
			
		||||
    > > > > > >
 | 
			
		||||
  : equality_comparable<T
 | 
			
		||||
  , less_than_comparable<T
 | 
			
		||||
  , incrementable<T
 | 
			
		||||
  , decrementable<T
 | 
			
		||||
  , dereferenceable<T,P
 | 
			
		||||
  , addable2<T,D
 | 
			
		||||
  , subtractable2<T,D
 | 
			
		||||
  , indexable<T,D,R
 | 
			
		||||
  , boost::iterator<std::random_access_iterator_tag,V,D,P,R
 | 
			
		||||
    > > > > > > > > >
 | 
			
		||||
{
 | 
			
		||||
#ifndef __BORLANDC__
 | 
			
		||||
  friend D requires_difference_operator(const T& x, const T& y) {
 | 
			
		||||
    return x - y;
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
}; // random_access_iterator_helper
 | 
			
		||||
 | 
			
		||||
} // namespace boost
 | 
			
		||||
 
 | 
			
		||||
@@ -11,9 +11,6 @@
 | 
			
		||||
//  Classes appear in alphabetical order
 | 
			
		||||
 | 
			
		||||
//  Revision History
 | 
			
		||||
//  21 May 01  checked_delete() and checked_array_delete() added (Beman Dawes,
 | 
			
		||||
//             suggested by Dave Abrahams, generalizing idea from Vladimir Prus)
 | 
			
		||||
//  21 May 01  made next() and prior() inline (Beman Dawes)  
 | 
			
		||||
//  26 Jan 00  protected noncopyable destructor added (Miki Jovanovic)
 | 
			
		||||
//  10 Dec 99  next() and prior() templates added (Dave Abrahams)
 | 
			
		||||
//  30 Aug 99  moved cast templates to cast.hpp (Beman Dawes)
 | 
			
		||||
@@ -25,32 +22,12 @@
 | 
			
		||||
#ifndef BOOST_UTILITY_HPP
 | 
			
		||||
#define BOOST_UTILITY_HPP
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>        // broken compiler workarounds 
 | 
			
		||||
#include <boost/static_assert.hpp> 
 | 
			
		||||
#include <cstddef>                 // for size_t
 | 
			
		||||
#include <utility>                 // for std::pair
 | 
			
		||||
#include <boost/config.hpp>
 | 
			
		||||
#include <cstddef>            // for size_t
 | 
			
		||||
#include <utility>            // for std::pair
 | 
			
		||||
 | 
			
		||||
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  -----------------------------------//
 | 
			
		||||
 | 
			
		||||
@@ -64,10 +41,10 @@ namespace boost
 | 
			
		||||
    //  Contributed by Dave Abrahams
 | 
			
		||||
 | 
			
		||||
    template <class T>
 | 
			
		||||
    inline T next(T x) { return ++x; }
 | 
			
		||||
    T next(T x) { return ++x; }
 | 
			
		||||
 | 
			
		||||
    template <class T>
 | 
			
		||||
    inline T prior(T x) { return --x; }
 | 
			
		||||
    T prior(T x) { return --x; }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//  class noncopyable  -------------------------------------------------------//
 | 
			
		||||
 
 | 
			
		||||
@@ -422,7 +422,7 @@ a,b,c,d,e,f,g,
 | 
			
		||||
    <hr>
 | 
			
		||||
 | 
			
		||||
    <p>Revised 
 | 
			
		||||
    <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->17 Aug 2001<!--webbot bot="Timestamp" endspan i-checksum="14763" -->
 | 
			
		||||
    <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->08 Mar 2001<!--webbot bot="Timestamp" endspan i-checksum="14892" -->
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    <p>© Copyright Jeremy Siek and David Abrahams 2001. Permission to
 | 
			
		||||
 
 | 
			
		||||
@@ -29,7 +29,8 @@ int main(int, char*[])
 | 
			
		||||
 | 
			
		||||
  // Example of using indirect_iterator_pair_generator
 | 
			
		||||
 | 
			
		||||
  typedef boost::indirect_iterator_pair_generator<char**, char> PairGen;
 | 
			
		||||
  typedef boost::indirect_iterator_pair_generator<char**,
 | 
			
		||||
    char, char*, char&, const char*, const char&> PairGen;
 | 
			
		||||
 | 
			
		||||
  char mutable_characters[N];
 | 
			
		||||
  char* pointers_to_mutable_chars[N];
 | 
			
		||||
 
 | 
			
		||||
@@ -93,7 +93,7 @@
 | 
			
		||||
       <a href="function_output_iterator.htm">Function Output Iterator Adaptor</a>
 | 
			
		||||
    </ul>
 | 
			
		||||
 | 
			
		||||
    <p><b><a href="../../people/dave_abrahams.htm">Dave
 | 
			
		||||
    <p><b><a href="http://www.boost.org/people/dave_abrahams.htm">Dave
 | 
			
		||||
    Abrahams</a></b> started the library, applying <a href=
 | 
			
		||||
    "../../more/generic_programming.html#policy">policy class</a> technique and
 | 
			
		||||
    handling const/non-const iterator interactions. He also contributed the
 | 
			
		||||
@@ -102,7 +102,7 @@
 | 
			
		||||
    <tt><a href="counting_iterator.htm">counting_iterator_generator</a></tt> to
 | 
			
		||||
    cover all incrementable types. He edited most of the documentation,
 | 
			
		||||
    sometimes heavily.<br>
 | 
			
		||||
     <b><a href="file:///c:/boost/site/people/jeremy_siek.htm">Jeremy
 | 
			
		||||
     <b><a href="http://www.boost.org/people/jeremy_siek.htm">Jeremy
 | 
			
		||||
    Siek</a></b> contributed the <a href="transform_iterator.htm">transform
 | 
			
		||||
    iterator</a> adaptor, the integer-only version of <tt><a href=
 | 
			
		||||
    "counting_iterator.htm">counting_iterator_generator</a></tt>, 
 | 
			
		||||
@@ -611,10 +611,10 @@ int main(int, char*[])
 | 
			
		||||
{
 | 
			
		||||
  int x[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
 | 
			
		||||
  const int N = sizeof(x)/sizeof(int);
 | 
			
		||||
  std::cout << "multiplying the array by 2:" << std::endl;
 | 
			
		||||
  std::cout << "multiplying the array by 2:" << std::endl;
 | 
			
		||||
  std::copy(boost::make_transform_iterator(x, std::bind1st(std::multiplies<int>(), 2)),
 | 
			
		||||
      boost::make_transform_iterator(x + N, std::bind1st(std::multiplies<int>(), 2)),
 | 
			
		||||
      std::ostream_iterator<int>(std::cout, " "));
 | 
			
		||||
      std::ostream_iterator<int>(std::cout, " "));
 | 
			
		||||
  std::cout << std::endl;
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
@@ -860,7 +860,7 @@ bool operator==(const iterator_adaptor<B1,P,V1,R1,P1,C,D>&,
 | 
			
		||||
    <hr>
 | 
			
		||||
 | 
			
		||||
    <p>Revised 
 | 
			
		||||
    <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->20 Aug 2001<!--webbot bot="Timestamp" endspan i-checksum="14750" -->
 | 
			
		||||
    <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->19 Mar 2001<!--webbot bot="Timestamp" endspan i-checksum="14895" -->
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    <p>© Copyright Dave Abrahams and Jeremy Siek 2001. Permission to copy,
 | 
			
		||||
 
 | 
			
		||||
@@ -9,29 +9,16 @@
 | 
			
		||||
//  See http://www.boost.org for most recent version including documentation.
 | 
			
		||||
 | 
			
		||||
//  Revision History
 | 
			
		||||
//  29 May 01 Factored implementation, added comparison tests, use Test Tools
 | 
			
		||||
//            library (Daryle Walker)
 | 
			
		||||
//  12 Dec 99 Initial version with iterator operators (Jeremy Siek)
 | 
			
		||||
 | 
			
		||||
#define  BOOST_INCLUDE_MAIN
 | 
			
		||||
#include <boost/test/test_tools.hpp>  // for main
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
using namespace std;
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>     // for BOOST_STATIC_CONSTANT
 | 
			
		||||
#include <boost/cstdlib.hpp>    // for boost::exit_success
 | 
			
		||||
#include <boost/operators.hpp>  // for boost::random_access_iterator_helper
 | 
			
		||||
 | 
			
		||||
#include <cstddef>    // for std::ptrdiff_t, std::size_t
 | 
			
		||||
#include <cstring>    // for std::strcmp
 | 
			
		||||
#include <iostream>   // for std::cout (std::endl, ends, and flush indirectly)
 | 
			
		||||
#include <string>     // for std::string
 | 
			
		||||
#include <strstream>  // for std::ostrstream
 | 
			
		||||
 | 
			
		||||
# ifdef BOOST_NO_STDC_NAMESPACE
 | 
			
		||||
    namespace std { using ::strcmp; }
 | 
			
		||||
# endif
 | 
			
		||||
#include <boost/operators.hpp>
 | 
			
		||||
using namespace boost;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Iterator test class
 | 
			
		||||
template <class T, class R, class P>
 | 
			
		||||
struct test_iter
 | 
			
		||||
  : public boost::random_access_iterator_helper<
 | 
			
		||||
@@ -42,7 +29,7 @@ struct test_iter
 | 
			
		||||
  typedef std::ptrdiff_t Distance;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
  explicit test_iter(T* i =0) : _i(i) { }
 | 
			
		||||
  test_iter(T* i) : _i(i) { }
 | 
			
		||||
  test_iter(const self& x) : _i(x._i) { }
 | 
			
		||||
  self& operator=(const self& x) { _i = x._i; return *this; }
 | 
			
		||||
  Reference operator*() const { return *_i; }
 | 
			
		||||
@@ -56,280 +43,127 @@ public:
 | 
			
		||||
    return x._i - y._i; 
 | 
			
		||||
  }
 | 
			
		||||
protected:
 | 
			
		||||
  P _i;
 | 
			
		||||
  T* _i;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Iterator operator testing classes
 | 
			
		||||
class test_opr_base
 | 
			
		||||
{
 | 
			
		||||
protected:
 | 
			
		||||
    // Test data and types
 | 
			
		||||
    BOOST_STATIC_CONSTANT( std::size_t, fruit_length = 6u );
 | 
			
		||||
    BOOST_STATIC_CONSTANT( std::size_t, scratch_length = 40u );
 | 
			
		||||
 | 
			
		||||
    typedef std::string  fruit_array_type[ fruit_length ];
 | 
			
		||||
    typedef char         scratch_array_type[ scratch_length ];
 | 
			
		||||
 | 
			
		||||
    static  fruit_array_type    fruit;
 | 
			
		||||
    static  scratch_array_type  scratch;
 | 
			
		||||
 | 
			
		||||
};  // test_opr_base
 | 
			
		||||
 | 
			
		||||
template <typename T, typename R = T&, typename P = T*>
 | 
			
		||||
class test_opr
 | 
			
		||||
    : public test_opr_base
 | 
			
		||||
{
 | 
			
		||||
    typedef test_opr<T, R, P>  self_type;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    // Types
 | 
			
		||||
    typedef T  value_type;
 | 
			
		||||
    typedef R  reference;
 | 
			
		||||
    typedef P  pointer;
 | 
			
		||||
 | 
			
		||||
    typedef test_iter<T, R, P>  iter_type;
 | 
			
		||||
 | 
			
		||||
    // Test controller
 | 
			
		||||
    static  void  master_test( char const name[] );
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    // Test data
 | 
			
		||||
    static  iter_type const  fruit_begin, fruit_end;
 | 
			
		||||
 | 
			
		||||
    // Test parts
 | 
			
		||||
    static  void  post_increment_test();
 | 
			
		||||
    static  void  post_decrement_test();
 | 
			
		||||
    static  void  indirect_referral_test();
 | 
			
		||||
    static  void  offset_addition_test();
 | 
			
		||||
    static  void  reverse_offset_addition_test();
 | 
			
		||||
    static  void  offset_subtraction_test();
 | 
			
		||||
    static  void  comparison_test();
 | 
			
		||||
    static  void  indexing_test();
 | 
			
		||||
 | 
			
		||||
};  // test_opr
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Class-static data definitions
 | 
			
		||||
test_opr_base::fruit_array_type
 | 
			
		||||
 test_opr_base::fruit = { "apple", "orange", "pear", "peach", "grape", "plum" };
 | 
			
		||||
 | 
			
		||||
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 );
 | 
			
		||||
 | 
			
		||||
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 );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Main testing function
 | 
			
		||||
int
 | 
			
		||||
test_main( int , char * [] )
 | 
			
		||||
main()
 | 
			
		||||
{
 | 
			
		||||
    using std::string;
 | 
			
		||||
  string array[] = { "apple", "orange", "pear", "peach", "grape", "plum"  };
 | 
			
		||||
  {
 | 
			
		||||
    test_iter<string,string&,string*> i = array, 
 | 
			
		||||
      ie = array + sizeof(array)/sizeof(string);
 | 
			
		||||
 | 
			
		||||
    typedef test_opr<string, string &, string *>              test1_type;
 | 
			
		||||
    typedef test_opr<string, string const &, string const *>  test2_type;
 | 
			
		||||
    // Tests for all of the operators added by random_access_iterator_helper
 | 
			
		||||
 | 
			
		||||
    test1_type::master_test( "non-const string" );
 | 
			
		||||
    test2_type::master_test( "const string" );
 | 
			
		||||
    // test i++
 | 
			
		||||
    while (i != ie)
 | 
			
		||||
      cout << *i++ << " ";
 | 
			
		||||
    cout << endl;
 | 
			
		||||
    i = array;
 | 
			
		||||
 | 
			
		||||
    return boost::exit_success;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Tests for all of the operators added by random_access_iterator_helper
 | 
			
		||||
template <typename T, typename R, typename P>
 | 
			
		||||
void
 | 
			
		||||
test_opr<T, R, P>::master_test
 | 
			
		||||
(
 | 
			
		||||
    char const  name[]
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
    std::cout << "Doing test run for " << name << '.' << std::endl;
 | 
			
		||||
 | 
			
		||||
    post_increment_test();
 | 
			
		||||
    post_decrement_test();
 | 
			
		||||
    indirect_referral_test();
 | 
			
		||||
    offset_addition_test();
 | 
			
		||||
    reverse_offset_addition_test();
 | 
			
		||||
    offset_subtraction_test();
 | 
			
		||||
    comparison_test();
 | 
			
		||||
    indexing_test();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Test post-increment
 | 
			
		||||
template <typename T, typename R, typename P>
 | 
			
		||||
void
 | 
			
		||||
test_opr<T, R, P>::post_increment_test
 | 
			
		||||
(
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
    std::cout << "\tDoing post-increment test." << std::endl;
 | 
			
		||||
 | 
			
		||||
    std::ostrstream  oss( scratch, scratch_length );
 | 
			
		||||
    for ( iter_type i = fruit_begin ; i != fruit_end ; )
 | 
			
		||||
    {
 | 
			
		||||
        oss << *i++ << ' ';
 | 
			
		||||
    // test i--
 | 
			
		||||
    while (ie != i) {
 | 
			
		||||
      ie--;
 | 
			
		||||
      cout << *ie << " ";
 | 
			
		||||
    }
 | 
			
		||||
    cout << endl;
 | 
			
		||||
    ie = array + sizeof(array)/sizeof(string);
 | 
			
		||||
 | 
			
		||||
    oss << std::ends;
 | 
			
		||||
    BOOST_TEST( std::strcmp(oss.str(), "apple orange pear peach grape plum ")
 | 
			
		||||
     == 0 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Test post-decrement
 | 
			
		||||
template <typename T, typename R, typename P>
 | 
			
		||||
void
 | 
			
		||||
test_opr<T, R, P>::post_decrement_test
 | 
			
		||||
(
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
    std::cout << "\tDoing post-decrement test." << std::endl;
 | 
			
		||||
 | 
			
		||||
    std::ostrstream  oss( scratch, scratch_length );
 | 
			
		||||
    for ( iter_type i = fruit_end ; i != fruit_begin ; )
 | 
			
		||||
    {
 | 
			
		||||
        i--;
 | 
			
		||||
        oss << *i << ' ';
 | 
			
		||||
    // test i->m
 | 
			
		||||
    while (i != ie) {
 | 
			
		||||
      cout << i->size() << " ";
 | 
			
		||||
      ++i;
 | 
			
		||||
    }
 | 
			
		||||
    cout << endl;
 | 
			
		||||
    i = array;
 | 
			
		||||
 | 
			
		||||
    oss << std::ends;
 | 
			
		||||
    BOOST_TEST( std::strcmp(oss.str(), "plum grape peach pear orange apple ")
 | 
			
		||||
     == 0 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Test indirect structure referral
 | 
			
		||||
template <typename T, typename R, typename P>
 | 
			
		||||
void
 | 
			
		||||
test_opr<T, R, P>::indirect_referral_test
 | 
			
		||||
(
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
    std::cout << "\tDoing indirect reference test." << std::endl;
 | 
			
		||||
 | 
			
		||||
    std::ostrstream  oss( scratch, scratch_length );
 | 
			
		||||
    for ( iter_type i = fruit_begin ; i != fruit_end ; ++i )
 | 
			
		||||
    {
 | 
			
		||||
        oss << i->size() << ' ';
 | 
			
		||||
    // test i + n
 | 
			
		||||
    while (i < ie) {
 | 
			
		||||
      cout << *i << " ";
 | 
			
		||||
      i = i + 2;
 | 
			
		||||
    }
 | 
			
		||||
    cout << endl;
 | 
			
		||||
    i = array;
 | 
			
		||||
 | 
			
		||||
    oss << std::ends;
 | 
			
		||||
    BOOST_TEST( std::strcmp(oss.str(), "5 6 4 5 5 4 ") == 0 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Test offset addition
 | 
			
		||||
template <typename T, typename R, typename P>
 | 
			
		||||
void
 | 
			
		||||
test_opr<T, R, P>::offset_addition_test
 | 
			
		||||
(
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
    std::cout << "\tDoing offset addition test." << std::endl;
 | 
			
		||||
 | 
			
		||||
    std::ptrdiff_t const  two = 2;
 | 
			
		||||
    std::ostrstream       oss( scratch, scratch_length );
 | 
			
		||||
    for ( iter_type i = fruit_begin ; i != fruit_end ; i = i + two )
 | 
			
		||||
    {
 | 
			
		||||
        oss << *i << ' ';
 | 
			
		||||
    // test n + i
 | 
			
		||||
    while (i < ie) {
 | 
			
		||||
      cout << *i << " ";
 | 
			
		||||
      i = ptrdiff_t(2) + i;
 | 
			
		||||
    }
 | 
			
		||||
    cout << endl;
 | 
			
		||||
    i = array;
 | 
			
		||||
 | 
			
		||||
    oss << std::ends;
 | 
			
		||||
    BOOST_TEST( std::strcmp(oss.str(), "apple pear grape ") == 0 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Test offset addition, in reverse order
 | 
			
		||||
template <typename T, typename R, typename P>
 | 
			
		||||
void
 | 
			
		||||
test_opr<T, R, P>::reverse_offset_addition_test
 | 
			
		||||
(
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
    std::cout << "\tDoing reverse offset addition test." << std::endl;
 | 
			
		||||
 | 
			
		||||
    std::ptrdiff_t const  two = 2;
 | 
			
		||||
    std::ostrstream       oss( scratch, scratch_length );
 | 
			
		||||
    for ( iter_type i = fruit_begin ; i != fruit_end ; i = two + i )
 | 
			
		||||
    {
 | 
			
		||||
        oss << *i << ' ';
 | 
			
		||||
    // test i - n
 | 
			
		||||
    while (ie > i) {
 | 
			
		||||
      ie = ie - 2;
 | 
			
		||||
      cout << *ie << " ";
 | 
			
		||||
    }
 | 
			
		||||
    cout << endl;
 | 
			
		||||
    ie = array + sizeof(array)/sizeof(string);
 | 
			
		||||
 | 
			
		||||
    oss << std::ends;
 | 
			
		||||
    BOOST_TEST( std::strcmp(oss.str(), "apple pear grape ") == 0 );
 | 
			
		||||
}
 | 
			
		||||
    // test i[n]
 | 
			
		||||
    for (std::size_t j = 0; j < sizeof(array)/sizeof(string); ++j)
 | 
			
		||||
      cout << i[j] << " ";
 | 
			
		||||
    cout << endl;
 | 
			
		||||
  }
 | 
			
		||||
  {
 | 
			
		||||
    test_iter<string, const string&, const string*> i = array, 
 | 
			
		||||
      ie = array + sizeof(array)/sizeof(string);
 | 
			
		||||
 | 
			
		||||
// Test offset subtraction
 | 
			
		||||
template <typename T, typename R, typename P>
 | 
			
		||||
void
 | 
			
		||||
test_opr<T, R, P>::offset_subtraction_test
 | 
			
		||||
(
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
    std::cout << "\tDoing offset subtraction test." << std::endl;
 | 
			
		||||
    // Tests for all of the operators added by random_access_iterator_helper
 | 
			
		||||
 | 
			
		||||
    std::ptrdiff_t const  two = 2;
 | 
			
		||||
    std::ostrstream       oss( scratch, scratch_length );
 | 
			
		||||
    for ( iter_type i = fruit_end ; fruit_begin < i ; )
 | 
			
		||||
    {
 | 
			
		||||
        i = i - two;
 | 
			
		||||
        if ( (fruit_begin < i) || (fruit_begin == i) )
 | 
			
		||||
        {
 | 
			
		||||
            oss << *i << ' ';
 | 
			
		||||
        }
 | 
			
		||||
    // test i++
 | 
			
		||||
    while (i != ie)
 | 
			
		||||
      cout << *i++ << " ";
 | 
			
		||||
    cout << endl;
 | 
			
		||||
    i = array;
 | 
			
		||||
 | 
			
		||||
    // test i--
 | 
			
		||||
    while (ie != i) {
 | 
			
		||||
      ie--;
 | 
			
		||||
      cout << *ie << " ";
 | 
			
		||||
    }
 | 
			
		||||
    cout << endl;
 | 
			
		||||
    ie = array + sizeof(array)/sizeof(string);
 | 
			
		||||
 | 
			
		||||
    oss << std::ends;
 | 
			
		||||
    BOOST_TEST( std::strcmp(oss.str(), "grape pear apple ") == 0 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Test comparisons
 | 
			
		||||
template <typename T, typename R, typename P>
 | 
			
		||||
void
 | 
			
		||||
test_opr<T, R, P>::comparison_test
 | 
			
		||||
(
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
    using std::cout;
 | 
			
		||||
    using std::ptrdiff_t;
 | 
			
		||||
 | 
			
		||||
    cout << "\tDoing comparison tests.\n\t\tPass:";
 | 
			
		||||
 | 
			
		||||
    for ( iter_type i = fruit_begin ; i != fruit_end ; ++i )
 | 
			
		||||
    {
 | 
			
		||||
        ptrdiff_t const  i_offset = i - fruit_begin;
 | 
			
		||||
 | 
			
		||||
        cout << ' ' << *i << std::flush;
 | 
			
		||||
        for ( iter_type j = fruit_begin ; j != fruit_end ; ++j )
 | 
			
		||||
        {
 | 
			
		||||
            ptrdiff_t const  j_offset = j - fruit_begin;
 | 
			
		||||
 | 
			
		||||
            BOOST_TEST( (i != j) == (i_offset != j_offset) );
 | 
			
		||||
            BOOST_TEST( (i > j) == (i_offset > j_offset) );
 | 
			
		||||
            BOOST_TEST( (i <= j) == (i_offset <= j_offset) );
 | 
			
		||||
            BOOST_TEST( (i >= j) == (i_offset >= j_offset) );
 | 
			
		||||
        }
 | 
			
		||||
    // test i->m
 | 
			
		||||
    while (i != ie) {
 | 
			
		||||
      cout << i->size() << " ";
 | 
			
		||||
      ++i;
 | 
			
		||||
    }
 | 
			
		||||
    cout << std::endl;
 | 
			
		||||
}
 | 
			
		||||
    cout << endl;
 | 
			
		||||
    i = array;
 | 
			
		||||
 | 
			
		||||
// Test indexing
 | 
			
		||||
template <typename T, typename R, typename P>
 | 
			
		||||
void
 | 
			
		||||
test_opr<T, R, P>::indexing_test
 | 
			
		||||
(
 | 
			
		||||
)
 | 
			
		||||
{
 | 
			
		||||
    std::cout << "\tDoing indexing test." << std::endl;
 | 
			
		||||
 | 
			
		||||
    std::ostrstream  oss( scratch, scratch_length );
 | 
			
		||||
    for ( std::size_t k = 0u ; k < fruit_length ; ++k )
 | 
			
		||||
    {
 | 
			
		||||
        oss << fruit_begin[ k ] << ' ';
 | 
			
		||||
    // test i + n
 | 
			
		||||
    while (i < ie) {
 | 
			
		||||
      cout << *i << " ";
 | 
			
		||||
      i = i + 2;
 | 
			
		||||
    }
 | 
			
		||||
    cout << endl;
 | 
			
		||||
    i = array;
 | 
			
		||||
 | 
			
		||||
    oss << std::ends;
 | 
			
		||||
    BOOST_TEST( std::strcmp(oss.str(), "apple orange pear peach grape plum ")
 | 
			
		||||
     == 0 );
 | 
			
		||||
    // test n + i
 | 
			
		||||
    while (i < ie) {
 | 
			
		||||
      cout << *i << " ";
 | 
			
		||||
      i = ptrdiff_t(2) + i;
 | 
			
		||||
    }
 | 
			
		||||
    cout << endl;
 | 
			
		||||
    i = array;
 | 
			
		||||
 | 
			
		||||
    // test i - n
 | 
			
		||||
    while (ie > i) {
 | 
			
		||||
      ie = ie - 2;
 | 
			
		||||
      cout << *ie << " ";
 | 
			
		||||
    }
 | 
			
		||||
    cout << endl;
 | 
			
		||||
    ie = array + sizeof(array)/sizeof(string);
 | 
			
		||||
 | 
			
		||||
    // test i[n]
 | 
			
		||||
    for (std::size_t j = 0; j < sizeof(array)/sizeof(string); ++j)
 | 
			
		||||
      cout << i[j] << " ";
 | 
			
		||||
    cout << endl;
 | 
			
		||||
  }
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,6 @@
 | 
			
		||||
//  See http://www.boost.org for most recent version including documentation.
 | 
			
		||||
 | 
			
		||||
//  Revision History
 | 
			
		||||
//  1  Apr 2001 Fixes for ICL; use BOOST_STATIC_CONSTANT
 | 
			
		||||
//  11 Feb 2001 Fixes for Borland (David Abrahams)
 | 
			
		||||
//  23 Jan 2001 Added test for wchar_t (David Abrahams)
 | 
			
		||||
//  23 Jan 2001 Now statically selecting a test for signed numbers to avoid
 | 
			
		||||
@@ -31,6 +30,13 @@
 | 
			
		||||
# include <limits>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// A macro for declaring class compile-time constants.
 | 
			
		||||
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
 | 
			
		||||
# define DECLARE_CLASS_CONST(type, init) static const type init
 | 
			
		||||
#else
 | 
			
		||||
# define DECLARE_CLASS_CONST(type, init) enum { init }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
// =================================================================================
 | 
			
		||||
// template class complement_traits<Number> --
 | 
			
		||||
//
 | 
			
		||||
@@ -47,8 +53,8 @@ template <unsigned size> struct complement; // forward
 | 
			
		||||
template <class Number, unsigned size>
 | 
			
		||||
struct complement_traits_aux
 | 
			
		||||
{
 | 
			
		||||
    BOOST_STATIC_CONSTANT(Number, max = complement<size>::template traits<Number>::max);
 | 
			
		||||
    BOOST_STATIC_CONSTANT(Number, min = complement<size>::template traits<Number>::min);
 | 
			
		||||
    DECLARE_CLASS_CONST(Number, max = complement<size>::template traits<Number>::max);
 | 
			
		||||
    DECLARE_CLASS_CONST(Number, min = complement<size>::template traits<Number>::min);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <unsigned size>
 | 
			
		||||
@@ -61,11 +67,11 @@ struct complement
 | 
			
		||||
        // indirection through complement_traits_aux neccessary to keep MSVC happy
 | 
			
		||||
        typedef complement_traits_aux<Number, size - 1> prev;
 | 
			
		||||
     public:
 | 
			
		||||
        BOOST_STATIC_CONSTANT(Number, max =
 | 
			
		||||
        DECLARE_CLASS_CONST(Number, max =
 | 
			
		||||
                            Number(Number(prev::max) << CHAR_BIT)
 | 
			
		||||
                            + Number(UCHAR_MAX));
 | 
			
		||||
        
 | 
			
		||||
        BOOST_STATIC_CONSTANT(Number, min = Number(Number(prev::min) << CHAR_BIT));
 | 
			
		||||
        DECLARE_CLASS_CONST(Number, min = Number(Number(prev::min) << CHAR_BIT));
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -79,8 +85,8 @@ template <> struct complement_base<false>
 | 
			
		||||
    template <class Number>
 | 
			
		||||
    struct values
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_STATIC_CONSTANT(Number, min = 0);
 | 
			
		||||
        BOOST_STATIC_CONSTANT(Number, max = UCHAR_MAX);
 | 
			
		||||
        DECLARE_CLASS_CONST(Number, min = 0);
 | 
			
		||||
        DECLARE_CLASS_CONST(Number, max = UCHAR_MAX);
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -89,8 +95,8 @@ template <> struct complement_base<true>
 | 
			
		||||
    template <class Number>
 | 
			
		||||
    struct values
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_STATIC_CONSTANT(Number, min = SCHAR_MIN);
 | 
			
		||||
        BOOST_STATIC_CONSTANT(Number, max = SCHAR_MAX);
 | 
			
		||||
        DECLARE_CLASS_CONST(Number, min = SCHAR_MIN);
 | 
			
		||||
        DECLARE_CLASS_CONST(Number, max = SCHAR_MAX);
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -101,10 +107,10 @@ struct complement<1>
 | 
			
		||||
    template <class Number>
 | 
			
		||||
    struct traits
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_STATIC_CONSTANT(bool, is_signed = boost::detail::is_signed<Number>::value);
 | 
			
		||||
        BOOST_STATIC_CONSTANT(Number, min =
 | 
			
		||||
        DECLARE_CLASS_CONST(bool, is_signed = boost::detail::is_signed<Number>::value);
 | 
			
		||||
        DECLARE_CLASS_CONST(Number, min =
 | 
			
		||||
                            complement_base<is_signed>::template values<Number>::min);
 | 
			
		||||
        BOOST_STATIC_CONSTANT(Number, max =
 | 
			
		||||
        DECLARE_CLASS_CONST(Number, max =
 | 
			
		||||
                            complement_base<is_signed>::template values<Number>::max);
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
@@ -115,8 +121,8 @@ struct complement<1>
 | 
			
		||||
template <class Number>
 | 
			
		||||
struct complement_traits
 | 
			
		||||
{
 | 
			
		||||
    BOOST_STATIC_CONSTANT(Number, max = (complement_traits_aux<Number, sizeof(Number)>::max));
 | 
			
		||||
    BOOST_STATIC_CONSTANT(Number, min = (complement_traits_aux<Number, sizeof(Number)>::min));
 | 
			
		||||
    DECLARE_CLASS_CONST(Number, max = (complement_traits_aux<Number, sizeof(Number)>::max));
 | 
			
		||||
    DECLARE_CLASS_CONST(Number, min = (complement_traits_aux<Number, sizeof(Number)>::min));
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// =================================================================================
 | 
			
		||||
@@ -145,9 +151,9 @@ template <> struct stream_as<signed char>  {
 | 
			
		||||
    typedef unsigned char t1; typedef unsigned t2;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_MSVC_STD_ITERATOR) // No intmax streaming built-in
 | 
			
		||||
#if defined(BOOST_MSVC) // No intmax streaming built-in
 | 
			
		||||
 | 
			
		||||
// With this library implementation, __int64 and __uint64 get streamed as strings
 | 
			
		||||
// On this platform, __int64 and __uint64 get streamed as strings
 | 
			
		||||
template <> struct stream_as<boost::uintmax_t> {
 | 
			
		||||
    typedef std::string t1;
 | 
			
		||||
    typedef std::string t2;
 | 
			
		||||
@@ -168,7 +174,7 @@ template <class T> struct promote
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#if defined(BOOST_MSVC_STD_ITERATOR) // No intmax streaming built-in
 | 
			
		||||
#if defined(BOOST_MSVC) // No intmax streaming built-in
 | 
			
		||||
 | 
			
		||||
// On this platform, stream them as long/unsigned long if they fit.
 | 
			
		||||
// Otherwise, write a string.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1563
									
								
								operators.htm
									
									
									
									
									
								
							
							
						
						
									
										1563
									
								
								operators.htm
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -8,26 +8,18 @@
 | 
			
		||||
//  See http://www.boost.org for most recent version including documentation.
 | 
			
		||||
 | 
			
		||||
//  Revision History
 | 
			
		||||
//  20 May 01 Output progress messages.  Added tests for new operator
 | 
			
		||||
//            templates.  Updated random number generator.  Changed tests to
 | 
			
		||||
//            use Boost Test Tools library.  (Daryle Walker)
 | 
			
		||||
//  04 Jun 00 Added regression test for a bug I found (David Abrahams)
 | 
			
		||||
//  17 Jun 00 Fix for broken compilers (Aleksey Gurtovoy)
 | 
			
		||||
//  ?? ??? 00 Major update to randomly test all one- and two- argument forms by
 | 
			
		||||
//            wrapping integral types and comparing the results of operations
 | 
			
		||||
//            to the results for the raw types (David Abrahams)
 | 
			
		||||
//            wrapping integral types and comparing the results of operations to
 | 
			
		||||
//            the results for the raw types (David Abrahams)
 | 
			
		||||
//  12 Dec 99 Minor update, output confirmation message.
 | 
			
		||||
//  15 Nov 99 Initial version
 | 
			
		||||
 | 
			
		||||
#define BOOST_INCLUDE_MAIN
 | 
			
		||||
 | 
			
		||||
#include <boost/config.hpp>                      // for BOOST_MSVC
 | 
			
		||||
#include <boost/cstdlib.hpp>                     // for boost::exit_success
 | 
			
		||||
#include <boost/operators.hpp>                   // for the tested items
 | 
			
		||||
#include <boost/random/linear_congruential.hpp>  // for boost::minstd_rand
 | 
			
		||||
#include <boost/test/test_tools.hpp>             // for main
 | 
			
		||||
 | 
			
		||||
#include <iostream>  // for std::cout (std::endl indirectly)
 | 
			
		||||
#include <boost/operators.hpp>
 | 
			
		||||
#include <cassert>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <boost/min_rand.hpp>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
namespace
 | 
			
		||||
@@ -36,18 +28,14 @@ namespace
 | 
			
		||||
    int true_value(int x) { return x; }
 | 
			
		||||
    long true_value(long x) { return x; }
 | 
			
		||||
    signed char true_value(signed char x) { return x; }
 | 
			
		||||
    short true_value(short x) { return x; }
 | 
			
		||||
    unsigned int true_value(unsigned int x) { return x; }
 | 
			
		||||
    unsigned long true_value(unsigned long x) { return x; }
 | 
			
		||||
    unsigned char true_value(unsigned char x) { return x; }
 | 
			
		||||
    unsigned short true_value(unsigned short x) { return x; }
 | 
			
		||||
 | 
			
		||||
    // The use of operators<> here tended to obscure
 | 
			
		||||
    // interactions with certain compiler bugs
 | 
			
		||||
    // The use of operators<> here tended to obscure interactions with certain
 | 
			
		||||
    // compiler bugs
 | 
			
		||||
    template <class T>
 | 
			
		||||
    class Wrapped1
 | 
			
		||||
        : boost::operators<Wrapped1<T> >
 | 
			
		||||
        , boost::shiftable<Wrapped1<T> >
 | 
			
		||||
    class Wrapped1 : boost::operators<Wrapped1<T> >
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        explicit Wrapped1( T v = T() ) : _value(v) {}
 | 
			
		||||
@@ -72,10 +60,6 @@ namespace
 | 
			
		||||
          { _value &= x._value; return *this; }
 | 
			
		||||
        Wrapped1& operator^=(const Wrapped1& x)
 | 
			
		||||
          { _value ^= x._value; return *this; }
 | 
			
		||||
        Wrapped1& operator<<=(const Wrapped1& x)
 | 
			
		||||
          { _value <<= x._value; return *this; }
 | 
			
		||||
        Wrapped1& operator>>=(const Wrapped1& x)
 | 
			
		||||
          { _value >>= x._value; return *this; }
 | 
			
		||||
        Wrapped1& operator++()               { ++_value; return *this; }
 | 
			
		||||
        Wrapped1& operator--()               { --_value; return *this; }
 | 
			
		||||
        
 | 
			
		||||
@@ -86,11 +70,9 @@ namespace
 | 
			
		||||
    T true_value(Wrapped1<T> x) { return x.value(); }    
 | 
			
		||||
 | 
			
		||||
    template <class T, class U>
 | 
			
		||||
    class Wrapped2
 | 
			
		||||
        : boost::operators<Wrapped2<T, U> >
 | 
			
		||||
        , boost::operators2<Wrapped2<T, U>, U>
 | 
			
		||||
        , boost::shiftable1<Wrapped2<T, U>
 | 
			
		||||
        , boost::shiftable2<Wrapped2<T, U>, U > >
 | 
			
		||||
    class Wrapped2 :
 | 
			
		||||
        boost::operators<Wrapped2<T, U> >,
 | 
			
		||||
        boost::operators2<Wrapped2<T, U>, U>
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        explicit Wrapped2( T v = T() ) : _value(v) {}
 | 
			
		||||
@@ -115,10 +97,6 @@ namespace
 | 
			
		||||
          { _value &= x._value; return *this; }
 | 
			
		||||
        Wrapped2& operator^=(const Wrapped2& x)
 | 
			
		||||
          { _value ^= x._value; return *this; }
 | 
			
		||||
        Wrapped2& operator<<=(const Wrapped2& x)
 | 
			
		||||
          { _value <<= x._value; return *this; }
 | 
			
		||||
        Wrapped2& operator>>=(const Wrapped2& x)
 | 
			
		||||
          { _value >>= x._value; return *this; }
 | 
			
		||||
        Wrapped2& operator++()                { ++_value; return *this; }
 | 
			
		||||
        Wrapped2& operator--()                { --_value; return *this; }
 | 
			
		||||
         
 | 
			
		||||
@@ -133,8 +111,6 @@ namespace
 | 
			
		||||
        Wrapped2& operator|=(U u) { _value |= u; return *this; }
 | 
			
		||||
        Wrapped2& operator&=(U u) { _value &= u; return *this; }
 | 
			
		||||
        Wrapped2& operator^=(U u) { _value ^= u; return *this; }
 | 
			
		||||
        Wrapped2& operator<<=(U u) { _value <<= u; return *this; }
 | 
			
		||||
        Wrapped2& operator>>=(U u) { _value >>= u; return *this; }
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
        T _value;
 | 
			
		||||
@@ -142,268 +118,203 @@ namespace
 | 
			
		||||
    template <class T, class U>
 | 
			
		||||
    T true_value(Wrapped2<T,U> x) { return x.value(); }
 | 
			
		||||
    
 | 
			
		||||
    template <class T>
 | 
			
		||||
    class Wrapped3
 | 
			
		||||
        : boost::equivalent<Wrapped3<T> >
 | 
			
		||||
        , boost::partially_ordered<Wrapped3<T> >
 | 
			
		||||
        , boost::equality_comparable<Wrapped3<T> >
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        explicit Wrapped3( T v = T() ) : _value(v) {}
 | 
			
		||||
        T value() const { return _value; }
 | 
			
		||||
 | 
			
		||||
        bool operator<(const Wrapped3& x) const { return _value < x._value; }
 | 
			
		||||
        
 | 
			
		||||
    private:
 | 
			
		||||
        T _value;
 | 
			
		||||
    };
 | 
			
		||||
    template <class T>
 | 
			
		||||
    T true_value(Wrapped3<T> x) { return x.value(); }    
 | 
			
		||||
 | 
			
		||||
    template <class T, class U>
 | 
			
		||||
    class Wrapped4
 | 
			
		||||
        : boost::equality_comparable1<Wrapped4<T, U>
 | 
			
		||||
        , boost::equivalent1<Wrapped4<T, U>
 | 
			
		||||
        , boost::partially_ordered1<Wrapped4<T, U> > > >
 | 
			
		||||
        , boost::partially_ordered2<Wrapped4<T, U>, U
 | 
			
		||||
        , boost::equivalent2<Wrapped4<T, U>, U
 | 
			
		||||
        , boost::equality_comparable2<Wrapped4<T, U>, U> > >
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        explicit Wrapped4( T v = T() ) : _value(v) {}
 | 
			
		||||
        T value() const { return _value; }
 | 
			
		||||
 | 
			
		||||
        bool operator<(const Wrapped4& x) const { return _value < x._value; }
 | 
			
		||||
         
 | 
			
		||||
        bool operator<(U u) const { return _value < u; }
 | 
			
		||||
        bool operator>(U u) const { return _value > u; }
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
        T _value;
 | 
			
		||||
    };
 | 
			
		||||
    template <class T, class U>
 | 
			
		||||
    T true_value(Wrapped4<T,U> x) { return x.value(); }
 | 
			
		||||
    
 | 
			
		||||
    //  MyInt uses only the single template-argument form of all_operators<>
 | 
			
		||||
    typedef Wrapped1<int> MyInt;
 | 
			
		||||
 | 
			
		||||
    typedef Wrapped2<long, long> MyLong;
 | 
			
		||||
 | 
			
		||||
    typedef Wrapped3<signed char> MyChar;
 | 
			
		||||
 | 
			
		||||
    typedef Wrapped4<short, short> MyShort;
 | 
			
		||||
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void sanity_check(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_TEST( true_value(y1) == true_value(y2) );
 | 
			
		||||
        BOOST_TEST( true_value(x1) == true_value(x2) );
 | 
			
		||||
        assert(true_value(y1) == true_value(y2));
 | 
			
		||||
        assert(true_value(x1) == true_value(x2));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_less_than_comparable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_TEST( (x1 < y1) == (x2 < y2) );
 | 
			
		||||
        BOOST_TEST( (x1 <= y1) == (x2 <= y2) );
 | 
			
		||||
        BOOST_TEST( (x1 >= y1) == (x2 >= y2) );
 | 
			
		||||
        BOOST_TEST( (x1 > y1) == (x2 > y2) );
 | 
			
		||||
        assert((x1 < y1) == (x2 < y2));
 | 
			
		||||
        assert((x1 <= y1) == (x2 <= y2));
 | 
			
		||||
        assert((x1 >= y1) == (x2 >= y2));
 | 
			
		||||
        assert((x1 > y1) == (x2 > y2));
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_less_than_comparable(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        sanity_check( x1, y1, x2, y2 );
 | 
			
		||||
        test_less_than_comparable_aux( x1, y1, x2, y2 );
 | 
			
		||||
        test_less_than_comparable_aux( y1, x1, y2, x2 );
 | 
			
		||||
        sanity_check(x1, y1, x2, y2);
 | 
			
		||||
        test_less_than_comparable_aux(x1, y1, x2, y2);
 | 
			
		||||
        test_less_than_comparable_aux(y1, x1, y2, x2);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_equality_comparable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_TEST( (x1 == y1) == (x2 == y2) );
 | 
			
		||||
        BOOST_TEST( (x1 != y1) == (x2 != y2) );
 | 
			
		||||
        assert((x1 == y1) == (x2 == y2));
 | 
			
		||||
        assert((x1 != y1) == (x2 != y2));
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_equality_comparable(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        sanity_check( x1, y1, x2, y2 );
 | 
			
		||||
        test_equality_comparable_aux( x1, y1, x2, y2 );
 | 
			
		||||
        test_equality_comparable_aux( y1, x1, y2, x2 );
 | 
			
		||||
        sanity_check(x1, y1, x2, y2);
 | 
			
		||||
        test_equality_comparable_aux(x1, y1, x2, y2);
 | 
			
		||||
        test_equality_comparable_aux(y1, x1, y2, x2);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_multipliable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_TEST( (x1 * y1).value() == (x2 * y2) );
 | 
			
		||||
        assert((x1 * y1).value() == (x2 * y2));
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_multipliable(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        sanity_check( x1, y1, x2, y2 );
 | 
			
		||||
        test_multipliable_aux( x1, y1, x2, y2 );
 | 
			
		||||
        test_multipliable_aux( y1, x1, y2, x2 );
 | 
			
		||||
        sanity_check(x1, y1, x2, y2);
 | 
			
		||||
        test_multipliable_aux(x1, y1, x2, y2);
 | 
			
		||||
        test_multipliable_aux(y1, x1, y2, x2);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_addable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_TEST( (x1 + y1).value() == (x2 + y2) );
 | 
			
		||||
        assert((x1 + y1).value() == (x2 + y2));
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_addable(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        sanity_check( x1, y1, x2, y2 );
 | 
			
		||||
        test_addable_aux( x1, y1, x2, y2 );
 | 
			
		||||
        test_addable_aux( y1, x1, y2, x2 );
 | 
			
		||||
        sanity_check(x1, y1, x2, y2);
 | 
			
		||||
        test_addable_aux(x1, y1, x2, y2);
 | 
			
		||||
        test_addable_aux(y1, x1, y2, x2);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_subtractable(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        sanity_check( x1, y1, x2, y2 );
 | 
			
		||||
        BOOST_TEST( (x1 - y1).value() == (x2 - y2) );
 | 
			
		||||
        sanity_check(x1, y1, x2, y2);
 | 
			
		||||
        assert((x1 - y1).value() == x2 - y2);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_dividable(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        sanity_check( x1, y1, x2, y2 );
 | 
			
		||||
        if ( y2 != 0 )
 | 
			
		||||
            BOOST_TEST( (x1 / y1).value() == (x2 / y2) );
 | 
			
		||||
        sanity_check(x1, y1, x2, y2);
 | 
			
		||||
        if (y2 != 0)
 | 
			
		||||
            assert((x1 / y1).value() == x2 / y2);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_modable(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        sanity_check( x1, y1, x2, y2 );
 | 
			
		||||
        if ( y2 != 0 )
 | 
			
		||||
            BOOST_TEST( (x1 % y1).value() == (x2 % y2) );
 | 
			
		||||
        sanity_check(x1, y1, x2, y2);
 | 
			
		||||
        if (y2 != 0)
 | 
			
		||||
            assert((x1 / y1).value() == x2 / y2);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_xorable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_TEST( (x1 ^ y1).value() == (x2 ^ y2) );
 | 
			
		||||
        assert((x1 ^ y1).value() == (x2 ^ y2));
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_xorable(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        sanity_check( x1, y1, x2, y2 );
 | 
			
		||||
        test_xorable_aux( x1, y1, x2, y2 );
 | 
			
		||||
        test_xorable_aux( y1, x1, y2, x2 );
 | 
			
		||||
        sanity_check(x1, y1, x2, y2);
 | 
			
		||||
        test_xorable_aux(x1, y1, x2, y2);
 | 
			
		||||
        test_xorable_aux(y1, x1, y2, x2);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_andable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_TEST( (x1 & y1).value() == (x2 & y2) );
 | 
			
		||||
        assert((x1 & y1).value() == (x2 & y2));
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_andable(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        sanity_check( x1, y1, x2, y2 );
 | 
			
		||||
        test_andable_aux( x1, y1, x2, y2 );
 | 
			
		||||
        test_andable_aux( y1, x1, y2, x2 );
 | 
			
		||||
        sanity_check(x1, y1, x2, y2);
 | 
			
		||||
        test_andable_aux(x1, y1, x2, y2);
 | 
			
		||||
        test_andable_aux(y1, x1, y2, x2);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_orable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_TEST( (x1 | y1).value() == (x2 | y2) );
 | 
			
		||||
        assert((x1 | y1).value() == (x2 | y2));
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_orable(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        sanity_check( x1, y1, x2, y2 );
 | 
			
		||||
        test_orable_aux( x1, y1, x2, y2 );
 | 
			
		||||
        test_orable_aux( y1, x1, y2, x2 );
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_left_shiftable(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        sanity_check( x1, y1, x2, y2 );
 | 
			
		||||
        BOOST_TEST( (x1 << y1).value() == (x2 << y2) );
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_right_shiftable(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        sanity_check( x1, y1, x2, y2 );
 | 
			
		||||
        BOOST_TEST( (x1 >> y1).value() == (x2 >> y2) );
 | 
			
		||||
        sanity_check(x1, y1, x2, y2);
 | 
			
		||||
        test_orable_aux(x1, y1, x2, y2);
 | 
			
		||||
        test_orable_aux(y1, x1, y2, x2);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template <class X1, class X2>
 | 
			
		||||
    void test_incrementable(X1 x1, X2 x2)
 | 
			
		||||
    {
 | 
			
		||||
        sanity_check( x1, x1, x2, x2 );
 | 
			
		||||
        BOOST_TEST( (x1++).value() == x2++ );
 | 
			
		||||
        BOOST_TEST( x1.value() == x2 );
 | 
			
		||||
        sanity_check(x1, x1, x2, x2);
 | 
			
		||||
        assert(x1++.value() == x2++);
 | 
			
		||||
        assert(x1.value() == x2);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template <class X1, class X2>
 | 
			
		||||
    void test_decrementable(X1 x1, X2 x2)
 | 
			
		||||
    {
 | 
			
		||||
        sanity_check( x1, x1, x2, x2 );
 | 
			
		||||
        BOOST_TEST( (x1--).value() == x2-- );
 | 
			
		||||
        BOOST_TEST( x1.value() == x2 );
 | 
			
		||||
        sanity_check(x1, x1, x2, x2);
 | 
			
		||||
        assert(x1--.value() == x2--);
 | 
			
		||||
        assert(x1.value() == x2);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template <class X1, class Y1, class X2, class Y2>
 | 
			
		||||
    void test_all(X1 x1, Y1 y1, X2 x2, Y2 y2)
 | 
			
		||||
    {
 | 
			
		||||
        test_less_than_comparable( x1, y1, x2, y2 );
 | 
			
		||||
        test_equality_comparable( x1, y1, x2, y2 );
 | 
			
		||||
        test_multipliable( x1, y1, x2, y2 );
 | 
			
		||||
        test_addable( x1, y1, x2, y2 );
 | 
			
		||||
        test_subtractable( x1, y1, x2, y2 );
 | 
			
		||||
        test_dividable( x1, y1, x2, y2 );
 | 
			
		||||
        test_modable( x1, y1, x2, y2 );
 | 
			
		||||
        test_xorable( x1, y1, x2, y2 );
 | 
			
		||||
        test_andable( x1, y1, x2, y2 );
 | 
			
		||||
        test_orable( x1, y1, x2, y2 );
 | 
			
		||||
        test_left_shiftable( x1, y1, x2, y2 );
 | 
			
		||||
        test_right_shiftable( x1, y1, x2, y2 );
 | 
			
		||||
        test_incrementable( x1, x2 );
 | 
			
		||||
        test_decrementable( x1, x2 );
 | 
			
		||||
        test_less_than_comparable(x1, y1, x2, y2);
 | 
			
		||||
        test_equality_comparable(x1, y1, x2, y2);
 | 
			
		||||
        test_multipliable(x1, y1, x2, y2);
 | 
			
		||||
        test_addable(x1, y1, x2, y2);
 | 
			
		||||
        test_subtractable(x1, y1, x2, y2);
 | 
			
		||||
        test_dividable(x1, y1, x2, y2);
 | 
			
		||||
        test_modable(x1, y1, x2, y2);
 | 
			
		||||
        test_xorable(x1, y1, x2, y2);
 | 
			
		||||
        test_andable(x1, y1, x2, y2);
 | 
			
		||||
        test_orable(x1, y1, x2, y2);
 | 
			
		||||
        test_incrementable(x1, x2);
 | 
			
		||||
        test_decrementable(x1, x2);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template <class Big, class Small>
 | 
			
		||||
    struct tester
 | 
			
		||||
    {
 | 
			
		||||
        void operator()(boost::minstd_rand& randomizer) const
 | 
			
		||||
        void operator()(boost::min_rand& randomizer) const
 | 
			
		||||
        {
 | 
			
		||||
            Big    b1 = Big( randomizer() );
 | 
			
		||||
            Big    b2 = Big( randomizer() );
 | 
			
		||||
            Small  s = Small( randomizer() );
 | 
			
		||||
            Big b1 = Big(randomizer());
 | 
			
		||||
            Big b2 = Big(randomizer());
 | 
			
		||||
            Small s = Small(randomizer());
 | 
			
		||||
            
 | 
			
		||||
            test_all( Wrapped1<Big>(b1), Wrapped1<Big>(b2), b1, b2 );
 | 
			
		||||
            test_all( Wrapped2<Big, Small>(b1), s, b1, s );
 | 
			
		||||
            test_all(Wrapped1<Big>(b1), Wrapped1<Big>(b2), b1, b2);
 | 
			
		||||
            test_all(Wrapped2<Big, Small>(b1), s, b1, s);
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // added as a regression test. We had a bug which this uncovered.
 | 
			
		||||
    struct Point
 | 
			
		||||
        : boost::addable<Point
 | 
			
		||||
        , boost::subtractable<Point> >
 | 
			
		||||
        : boost::addable<Point,
 | 
			
		||||
        boost::subtractable<Point> >
 | 
			
		||||
    {
 | 
			
		||||
        Point( int h, int v ) : h(h), v(v) {}
 | 
			
		||||
        Point() :h(0), v(0) {}
 | 
			
		||||
        const Point& operator+=( const Point& rhs )
 | 
			
		||||
            { h += rhs.h; v += rhs.v; return *this; }
 | 
			
		||||
        const Point& operator-=( const Point& rhs )
 | 
			
		||||
            { h -= rhs.h; v -= rhs.v; return *this; }
 | 
			
		||||
        const Point& operator+=( const Point& rhs ) { h += rhs.h; v += rhs.v; return *this; }
 | 
			
		||||
        const Point& operator-=( const Point& rhs ) { h -= rhs.h; v -= rhs.v; return *this; }
 | 
			
		||||
 | 
			
		||||
        int h;
 | 
			
		||||
        int v;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
} // unnamed namespace
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -429,25 +340,20 @@ template Wrapped2<unsigned long, unsigned char>;
 | 
			
		||||
template Wrapped2<unsigned long, unsigned long>;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define PRIVATE_EXPR_TEST(e, t)  BOOST_TEST( ((e), (t)) )
 | 
			
		||||
#ifdef NDEBUG
 | 
			
		||||
#error This program is pointless when NDEBUG disables assert()!
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
test_main( int , char * [] )
 | 
			
		||||
int main()
 | 
			
		||||
{
 | 
			
		||||
    using std::cout;
 | 
			
		||||
    using std::endl;
 | 
			
		||||
 | 
			
		||||
    // Regression test.
 | 
			
		||||
    Point x;
 | 
			
		||||
    x = x + Point(3, 4);
 | 
			
		||||
    x = x - Point(3, 4);
 | 
			
		||||
    
 | 
			
		||||
    cout << "Created point, and operated on it." << endl;
 | 
			
		||||
    
 | 
			
		||||
    for (int n = 0; n < 10000; ++n)
 | 
			
		||||
    {
 | 
			
		||||
        boost::minstd_rand r;
 | 
			
		||||
        boost::min_rand r;
 | 
			
		||||
        tester<long, int>()(r);
 | 
			
		||||
        tester<long, signed char>()(r);
 | 
			
		||||
        tester<long, long>()(r);
 | 
			
		||||
@@ -461,197 +367,115 @@ test_main( int , char * [] )
 | 
			
		||||
        tester<unsigned int, unsigned char>()(r);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    cout << "Did random tester loop." << endl;
 | 
			
		||||
 | 
			
		||||
    MyInt i1(1);
 | 
			
		||||
    MyInt i2(2);
 | 
			
		||||
    MyInt i;
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( i1.value() == 1 );
 | 
			
		||||
    BOOST_TEST( i2.value() == 2 );
 | 
			
		||||
    BOOST_TEST( i.value() == 0 );
 | 
			
		||||
    assert( i1.value() == 1 );
 | 
			
		||||
    assert( i2.value() == 2 );
 | 
			
		||||
    assert( i.value() == 0 );
 | 
			
		||||
 | 
			
		||||
    cout << "Created MyInt objects.\n";
 | 
			
		||||
    i = i2;
 | 
			
		||||
    assert( i.value() == 2 );
 | 
			
		||||
    assert( i2 == i );
 | 
			
		||||
    assert( i1 != i2 );
 | 
			
		||||
    assert( i1 <  i2 );
 | 
			
		||||
    assert( i1 <= i2 );
 | 
			
		||||
    assert( i <= i2 );
 | 
			
		||||
    assert( i2 >  i1 );
 | 
			
		||||
    assert( i2 >= i1 );
 | 
			
		||||
    assert( i2 >= i );
 | 
			
		||||
 | 
			
		||||
    PRIVATE_EXPR_TEST( (i = i2), (i.value() == 2) );
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( i2 == i );
 | 
			
		||||
    BOOST_TEST( i1 != i2 );
 | 
			
		||||
    BOOST_TEST( i1 <  i2 );
 | 
			
		||||
    BOOST_TEST( i1 <= i2 );
 | 
			
		||||
    BOOST_TEST( i <= i2 );
 | 
			
		||||
    BOOST_TEST( i2 >  i1 );
 | 
			
		||||
    BOOST_TEST( i2 >= i1 );
 | 
			
		||||
    BOOST_TEST( i2 >= i );
 | 
			
		||||
 | 
			
		||||
    PRIVATE_EXPR_TEST( (i = i1 + i2), (i.value() == 3) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (i = i + i2), (i.value() == 5) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (i = i - i1), (i.value() == 4) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (i = i * i2), (i.value() == 8) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (i = i / i2), (i.value() == 4) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (i = i % ( i - i1 )), (i.value() == 1) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (i = i2 + i2), (i.value() == 4) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (i = i1 | i2 | i), (i.value() == 7) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (i = i & i2), (i.value() == 2) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (i = i + i1), (i.value() == 3) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (i = i ^ i1), (i.value() == 2) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (i = ( i + i1 ) * ( i2 | i1 )), (i.value() == 9) );
 | 
			
		||||
 | 
			
		||||
    PRIVATE_EXPR_TEST( (i = i1 << i2), (i.value() == 4) );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (i = i2 >> i1), (i.value() == 1) );
 | 
			
		||||
    i = i1 + i2; assert( i.value() == 3 );
 | 
			
		||||
    i = i + i2; assert( i.value() == 5 );
 | 
			
		||||
    i = i - i1; assert( i.value() == 4 );
 | 
			
		||||
    i = i * i2; assert( i.value() == 8 );
 | 
			
		||||
    i = i / i2; assert( i.value() == 4 );
 | 
			
		||||
    i = i % (i - i1); assert( i.value() == 1 );
 | 
			
		||||
    i = i2 + i2; assert( i.value() == 4 );
 | 
			
		||||
    i = i1 | i2 | i; assert( i.value() == 7 );
 | 
			
		||||
    i = i & i2; assert( i.value() == 2 );
 | 
			
		||||
    i = i + i1; assert( i.value() == 3 );
 | 
			
		||||
    i = i ^ i1; assert( i.value() == 2 );
 | 
			
		||||
    i = (i+i1)*(i2|i1); assert( i.value() == 9 );
 | 
			
		||||
    
 | 
			
		||||
    cout << "Performed tests on MyInt objects.\n";
 | 
			
		||||
 | 
			
		||||
    MyLong j1(1);
 | 
			
		||||
    MyLong j2(2);
 | 
			
		||||
    MyLong j;
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( j1.value() == 1 );
 | 
			
		||||
    BOOST_TEST( j2.value() == 2 );
 | 
			
		||||
    BOOST_TEST( j.value() == 0 );
 | 
			
		||||
    assert( j1.value() == 1 );
 | 
			
		||||
    assert( j2.value() == 2 );
 | 
			
		||||
    assert( j.value() == 0 );
 | 
			
		||||
 | 
			
		||||
    cout << "Created MyLong objects.\n";
 | 
			
		||||
    j = j2;
 | 
			
		||||
    assert( j.value() == 2 );
 | 
			
		||||
    
 | 
			
		||||
    assert( j2 == j );
 | 
			
		||||
    assert( 2 == j );
 | 
			
		||||
    assert( j2 == 2 );    
 | 
			
		||||
    assert( j == j2 );
 | 
			
		||||
    assert( j1 != j2 );
 | 
			
		||||
    assert( j1 != 2 );
 | 
			
		||||
    assert( 1 != j2 );
 | 
			
		||||
    assert( j1 <  j2 );
 | 
			
		||||
    assert( 1 <  j2 );
 | 
			
		||||
    assert( j1 <  2 );
 | 
			
		||||
    assert( j1 <= j2 );
 | 
			
		||||
    assert( 1 <= j2 );
 | 
			
		||||
    assert( j1 <= j );
 | 
			
		||||
    assert( j <= j2 );
 | 
			
		||||
    assert( 2 <= j2 );
 | 
			
		||||
    assert( j <= 2 );
 | 
			
		||||
    assert( j2 >  j1 );
 | 
			
		||||
    assert( 2 >  j1 );
 | 
			
		||||
    assert( j2 >  1 );
 | 
			
		||||
    assert( j2 >= j1 );
 | 
			
		||||
    assert( 2 >= j1 );
 | 
			
		||||
    assert( j2 >= 1 );
 | 
			
		||||
    assert( j2 >= j );
 | 
			
		||||
    assert( 2 >= j );
 | 
			
		||||
    assert( j2 >= 2 );
 | 
			
		||||
 | 
			
		||||
    PRIVATE_EXPR_TEST( (j = j2), (j.value() == 2) );
 | 
			
		||||
    assert( (j1 + 2) == 3 );
 | 
			
		||||
    assert( (1 + j2) == 3 );
 | 
			
		||||
    j = j1 + j2; assert( j.value() == 3 );
 | 
			
		||||
    
 | 
			
		||||
    BOOST_TEST( j2 == j );
 | 
			
		||||
    BOOST_TEST( 2 == j );
 | 
			
		||||
    BOOST_TEST( j2 == 2 );    
 | 
			
		||||
    BOOST_TEST( j == j2 );
 | 
			
		||||
    BOOST_TEST( j1 != j2 );
 | 
			
		||||
    BOOST_TEST( j1 != 2 );
 | 
			
		||||
    BOOST_TEST( 1 != j2 );
 | 
			
		||||
    BOOST_TEST( j1 <  j2 );
 | 
			
		||||
    BOOST_TEST( 1 <  j2 );
 | 
			
		||||
    BOOST_TEST( j1 <  2 );
 | 
			
		||||
    BOOST_TEST( j1 <= j2 );
 | 
			
		||||
    BOOST_TEST( 1 <= j2 );
 | 
			
		||||
    BOOST_TEST( j1 <= j );
 | 
			
		||||
    BOOST_TEST( j <= j2 );
 | 
			
		||||
    BOOST_TEST( 2 <= j2 );
 | 
			
		||||
    BOOST_TEST( j <= 2 );
 | 
			
		||||
    BOOST_TEST( j2 >  j1 );
 | 
			
		||||
    BOOST_TEST( 2 >  j1 );
 | 
			
		||||
    BOOST_TEST( j2 >  1 );
 | 
			
		||||
    BOOST_TEST( j2 >= j1 );
 | 
			
		||||
    BOOST_TEST( 2 >= j1 );
 | 
			
		||||
    BOOST_TEST( j2 >= 1 );
 | 
			
		||||
    BOOST_TEST( j2 >= j );
 | 
			
		||||
    BOOST_TEST( 2 >= j );
 | 
			
		||||
    BOOST_TEST( j2 >= 2 );
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( (j1 + 2) == 3 );
 | 
			
		||||
    BOOST_TEST( (1 + j2) == 3 );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (j = j1 + j2), (j.value() == 3) );
 | 
			
		||||
    assert( (j + 2) == 5 );
 | 
			
		||||
    assert( (3 + j2) == 5 );
 | 
			
		||||
    j = j + j2; assert( j.value() == 5 );
 | 
			
		||||
    
 | 
			
		||||
    BOOST_TEST( (j + 2) == 5 );
 | 
			
		||||
    BOOST_TEST( (3 + j2) == 5 );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (j = j + j2), (j.value() == 5) );
 | 
			
		||||
    assert( (j - 1) == 4 );
 | 
			
		||||
    j = j - j1; assert( j.value() == 4 );
 | 
			
		||||
    
 | 
			
		||||
    BOOST_TEST( (j - 1) == 4 );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (j = j - j1), (j.value() == 4) );
 | 
			
		||||
    assert( (j * 2) == 8 );
 | 
			
		||||
    assert( (4 * j2) == 8 );
 | 
			
		||||
    j = j * j2; assert( j.value() == 8 );
 | 
			
		||||
    
 | 
			
		||||
    BOOST_TEST( (j * 2) == 8 );
 | 
			
		||||
    BOOST_TEST( (4 * j2) == 8 );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (j = j * j2), (j.value() == 8) );
 | 
			
		||||
    assert( (j / 2) == 4 );
 | 
			
		||||
    j = j / j2; assert( j.value() == 4 );
 | 
			
		||||
    
 | 
			
		||||
    BOOST_TEST( (j / 2) == 4 );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (j = j / j2), (j.value() == 4) );
 | 
			
		||||
    assert( (j % 3) == 1 );
 | 
			
		||||
    j = j % (j - j1); assert( j.value() == 1 );
 | 
			
		||||
    
 | 
			
		||||
    BOOST_TEST( (j % 3) == 1 );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (j = j % ( j - j1 )), (j.value() == 1) );
 | 
			
		||||
    j = j2 + j2; assert( j.value() == 4 );
 | 
			
		||||
    
 | 
			
		||||
    PRIVATE_EXPR_TEST( (j = j2 + j2), (j.value() == 4) );
 | 
			
		||||
    assert( (1 | j2 | j) == 7 );
 | 
			
		||||
    assert( (j1 | 2 | j) == 7 );
 | 
			
		||||
    assert( (j1 | j2 | 4) == 7 );
 | 
			
		||||
    j = j1 | j2 | j; assert( j.value() == 7 );
 | 
			
		||||
    
 | 
			
		||||
    BOOST_TEST( (1 | j2 | j) == 7 );
 | 
			
		||||
    BOOST_TEST( (j1 | 2 | j) == 7 );
 | 
			
		||||
    BOOST_TEST( (j1 | j2 | 4) == 7 );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (j = j1 | j2 | j), (j.value() == 7) );
 | 
			
		||||
    assert( (7 & j2) == 2 );
 | 
			
		||||
    assert( (j & 2) == 2 );
 | 
			
		||||
    j = j & j2; assert( j.value() == 2 );
 | 
			
		||||
    
 | 
			
		||||
    BOOST_TEST( (7 & j2) == 2 );
 | 
			
		||||
    BOOST_TEST( (j & 2) == 2 );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (j = j & j2), (j.value() == 2) );
 | 
			
		||||
    j = j | j1; assert( j.value() == 3 );
 | 
			
		||||
    
 | 
			
		||||
    PRIVATE_EXPR_TEST( (j = j | j1), (j.value() == 3) );
 | 
			
		||||
    assert( (3 ^ j1) == 2 );
 | 
			
		||||
    assert( (j ^ 1) == 2 );
 | 
			
		||||
    j = j ^ j1; assert( j.value() == 2 );
 | 
			
		||||
    
 | 
			
		||||
    BOOST_TEST( (3 ^ j1) == 2 );
 | 
			
		||||
    BOOST_TEST( (j ^ 1) == 2 );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (j = j ^ j1), (j.value() == 2) );
 | 
			
		||||
    j = (j+j1)*(j2|j1); assert( j.value() == 9 );
 | 
			
		||||
    
 | 
			
		||||
    PRIVATE_EXPR_TEST( (j = ( j + j1 ) * ( j2 | j1 )), (j.value() == 9) );
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( (j1 << 2) == 4 );
 | 
			
		||||
    BOOST_TEST( (j2 << 1) == 4 );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (j = j1 << j2), (j.value() == 4) );
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( (j >> 2) == 1 );
 | 
			
		||||
    BOOST_TEST( (j2 >> 1) == 1 );
 | 
			
		||||
    PRIVATE_EXPR_TEST( (j = j2 >> j1), (j.value() == 1) );
 | 
			
		||||
    
 | 
			
		||||
    cout << "Performed tests on MyLong objects.\n";
 | 
			
		||||
 | 
			
		||||
    MyChar k1(1);
 | 
			
		||||
    MyChar k2(2);
 | 
			
		||||
    MyChar k;
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( k1.value() == 1 );
 | 
			
		||||
    BOOST_TEST( k2.value() == 2 );
 | 
			
		||||
    BOOST_TEST( k.value() == 0 );
 | 
			
		||||
 | 
			
		||||
    cout << "Created MyChar objects.\n";
 | 
			
		||||
 | 
			
		||||
    PRIVATE_EXPR_TEST( (k = k2), (k.value() == 2) );
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( k2 == k );
 | 
			
		||||
    BOOST_TEST( k1 != k2 );
 | 
			
		||||
    BOOST_TEST( k1 <  k2 );
 | 
			
		||||
    BOOST_TEST( k1 <= k2 );
 | 
			
		||||
    BOOST_TEST( k <= k2 );
 | 
			
		||||
    BOOST_TEST( k2 >  k1 );
 | 
			
		||||
    BOOST_TEST( k2 >= k1 );
 | 
			
		||||
    BOOST_TEST( k2 >= k );
 | 
			
		||||
    
 | 
			
		||||
    cout << "Performed tests on MyChar objects.\n";
 | 
			
		||||
 | 
			
		||||
    MyShort l1(1);
 | 
			
		||||
    MyShort l2(2);
 | 
			
		||||
    MyShort l;
 | 
			
		||||
 | 
			
		||||
    BOOST_TEST( l1.value() == 1 );
 | 
			
		||||
    BOOST_TEST( l2.value() == 2 );
 | 
			
		||||
    BOOST_TEST( l.value() == 0 );
 | 
			
		||||
 | 
			
		||||
    cout << "Created MyShort objects.\n";
 | 
			
		||||
 | 
			
		||||
    PRIVATE_EXPR_TEST( (l = l2), (l.value() == 2) );
 | 
			
		||||
    
 | 
			
		||||
    BOOST_TEST( l2 == l );
 | 
			
		||||
    BOOST_TEST( 2 == l );
 | 
			
		||||
    BOOST_TEST( l2 == 2 );    
 | 
			
		||||
    BOOST_TEST( l == l2 );
 | 
			
		||||
    BOOST_TEST( l1 != l2 );
 | 
			
		||||
    BOOST_TEST( l1 != 2 );
 | 
			
		||||
    BOOST_TEST( 1 != l2 );
 | 
			
		||||
    BOOST_TEST( l1 <  l2 );
 | 
			
		||||
    BOOST_TEST( 1 <  l2 );
 | 
			
		||||
    BOOST_TEST( l1 <  2 );
 | 
			
		||||
    BOOST_TEST( l1 <= l2 );
 | 
			
		||||
    BOOST_TEST( 1 <= l2 );
 | 
			
		||||
    BOOST_TEST( l1 <= l );
 | 
			
		||||
    BOOST_TEST( l <= l2 );
 | 
			
		||||
    BOOST_TEST( 2 <= l2 );
 | 
			
		||||
    BOOST_TEST( l <= 2 );
 | 
			
		||||
    BOOST_TEST( l2 >  l1 );
 | 
			
		||||
    BOOST_TEST( 2 >  l1 );
 | 
			
		||||
    BOOST_TEST( l2 >  1 );
 | 
			
		||||
    BOOST_TEST( l2 >= l1 );
 | 
			
		||||
    BOOST_TEST( 2 >= l1 );
 | 
			
		||||
    BOOST_TEST( l2 >= 1 );
 | 
			
		||||
    BOOST_TEST( l2 >= l );
 | 
			
		||||
    BOOST_TEST( 2 >= l );
 | 
			
		||||
    BOOST_TEST( l2 >= 2 );
 | 
			
		||||
    
 | 
			
		||||
    cout << "Performed tests on MyShort objects.\n";
 | 
			
		||||
    
 | 
			
		||||
    return boost::exit_success;
 | 
			
		||||
    std::cout << "0 errors detected\n";
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -371,7 +371,7 @@ Betty
 | 
			
		||||
</pre>
 | 
			
		||||
 | 
			
		||||
<hr>
 | 
			
		||||
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->17 Aug 2001<!--webbot bot="Timestamp" endspan i-checksum="14763" --></p>
 | 
			
		||||
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->08 Mar 2001<!--webbot bot="Timestamp" endspan i-checksum="14892" --></p>
 | 
			
		||||
<p><EFBFBD> Copyright Jeremy Siek 2000. Permission to copy, use,
 | 
			
		||||
modify, sell and distribute this document is granted provided this copyright
 | 
			
		||||
notice appears in all copies. This document is provided "as is"
 | 
			
		||||
 
 | 
			
		||||
@@ -312,7 +312,7 @@ simply use <tt>reverse_iterator_generator</tt> twice!<br><br>
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    <p>Revised 
 | 
			
		||||
    <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->17 Aug 2001<!--webbot bot="Timestamp" endspan i-checksum="14763" -->
 | 
			
		||||
    <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->08 Mar 2001<!--webbot bot="Timestamp" endspan i-checksum="14892" -->
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    <p>© Copyright Jeremy Siek 2000. Permission to copy, use, modify, sell
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								tie.html
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								tie.html
									
									
									
									
									
								
							@@ -23,9 +23,7 @@
 | 
			
		||||
<TT>tie</TT>
 | 
			
		||||
</H1>
 | 
			
		||||
 | 
			
		||||
<h3>
 | 
			
		||||
[tie has been deprecated.  Its functionality is supplied by the Boost
 | 
			
		||||
Tuples Library.]</h3>
 | 
			
		||||
<P>
 | 
			
		||||
<PRE>
 | 
			
		||||
template <class A, class B>
 | 
			
		||||
tied<A,B> tie(A& a, B& b);
 | 
			
		||||
@@ -126,7 +124,7 @@ The output is:
 | 
			
		||||
<TABLE>
 | 
			
		||||
<TR valign=top>
 | 
			
		||||
<TD nowrap>Copyright © 2000</TD><TD>
 | 
			
		||||
<a HREF="../../people/jeremy_siek.htm">Jeremy Siek</a>,
 | 
			
		||||
<A HREF=http://www.boost.org/people/jeremy_siek.htm>Jeremy Siek</A>,
 | 
			
		||||
Univ.of Notre Dame (<A
 | 
			
		||||
HREF="mailto:jsiek@lsc.nd.edu">jsiek@lsc.nd.edu</A>)<br>
 | 
			
		||||
<A HREF=http://www.lsc.nd.edu/~llee1>Lie-Quan Lee</A>, Univ.of Notre Dame (<A HREF="mailto:llee1@lsc.nd.edu">llee1@lsc.nd.edu</A>)<br>
 | 
			
		||||
 
 | 
			
		||||
@@ -211,7 +211,7 @@ iterator always returns by-value.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<hr>
 | 
			
		||||
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->17 Aug 2001<!--webbot bot="Timestamp" endspan i-checksum="14763" --></p>
 | 
			
		||||
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->29 Mar 2001<!--webbot bot="Timestamp" endspan i-checksum="14896" --></p>
 | 
			
		||||
<p><EFBFBD> Copyright Jeremy Siek 2000. Permission to copy, use,
 | 
			
		||||
modify, sell and distribute this document is granted provided this copyright
 | 
			
		||||
notice appears in all copies. This document is provided "as is"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										44
									
								
								utility.htm
									
									
									
									
									
								
							
							
						
						
									
										44
									
								
								utility.htm
									
									
									
									
									
								
							@@ -16,50 +16,10 @@
 | 
			
		||||
<h2>Contents</h2>
 | 
			
		||||
 | 
			
		||||
<ul>
 | 
			
		||||
  <li>Function templates <a href="#checked_delete">checked_delete() and
 | 
			
		||||
    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="tie.html">tie()</a> and supporting class tied.</li>
 | 
			
		||||
</ul>
 | 
			
		||||
<h2> Function templates <a name="checked_delete">checked_delete</a>() and
 | 
			
		||||
checked_array_delete()</h2>
 | 
			
		||||
 | 
			
		||||
<p>Deletion of a pointer to an incomplete type is an unsafe programming practice
 | 
			
		||||
because there is no way for the compiler to verify that the destructor is indeed
 | 
			
		||||
trivial.  The checked_delete() and checked_array_delete() function
 | 
			
		||||
templates simply <b>delete</b> or <b>delete[]</b> their argument, but also
 | 
			
		||||
require that their argument be a complete type.  They issue an appropriate
 | 
			
		||||
compiler error diagnostic if that requirement is not met.  A typical
 | 
			
		||||
implementation is shown; other implementations may vary:</p>
 | 
			
		||||
 | 
			
		||||
<pre>    template< typename T >
 | 
			
		||||
    inline void checked_delete(T const volatile * x)
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_STATIC_ASSERT( sizeof(T) ); // assert type complete at point
 | 
			
		||||
                                          // of instantiation
 | 
			
		||||
        delete x;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template< typename T >
 | 
			
		||||
    inline void checked_array_delete(T const volatile * x)
 | 
			
		||||
    {
 | 
			
		||||
        BOOST_STATIC_ASSERT( sizeof(T) ); // assert type complete at point
 | 
			
		||||
                                          // of instantiation
 | 
			
		||||
        delete [] x;
 | 
			
		||||
    }</pre>
 | 
			
		||||
 | 
			
		||||
<p>Contributed by Beman Dawes, based on a suggestion from Dave Abrahams,
 | 
			
		||||
generalizing an idea from Vladimir Prus, with comments from Rainer Deyke, John
 | 
			
		||||
Maddock, and others.</p>
 | 
			
		||||
 | 
			
		||||
<h3>Background</h3>
 | 
			
		||||
 | 
			
		||||
<p>The C++ Standard specifies that delete on a pointer to an incomplete types is
 | 
			
		||||
undefined behavior if the type has a non-trivial destructor in  [expr.delete]
 | 
			
		||||
5.3.5 paragraph.  No diagnostic is required.  Some but not all
 | 
			
		||||
compilers issue warnings if the type is incomplete at point of deletion.</p>
 | 
			
		||||
 | 
			
		||||
<h2> <a name="functions next">Function</a> templates next() and prior()</h2>
 | 
			
		||||
 | 
			
		||||
<p>Certain data types, such as the C++ Standard Library's forward and
 | 
			
		||||
@@ -131,11 +91,9 @@ 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>Function template tie()</h2>
 | 
			
		||||
<p>See <a href="tie.html">separate documentation</a>.</p>
 | 
			
		||||
<hr>
 | 
			
		||||
<p>Revised  <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan
 | 
			
		||||
-->22 May, 2001<!--webbot bot="Timestamp" endspan i-checksum="13960"
 | 
			
		||||
-->08 March, 2001<!--webbot bot="Timestamp" endspan i-checksum="28780"
 | 
			
		||||
-->
 | 
			
		||||
</p>
 | 
			
		||||
<p><EFBFBD> Copyright boost.org 1999. Permission to copy, use, modify, sell and
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user