mirror of
https://github.com/boostorg/utility.git
synced 2025-10-08 14:50:54 +02:00
Compare commits
1 Commits
svn-branch
...
boost-1.21
Author | SHA1 | Date | |
---|---|---|---|
|
9c553546a5 |
@@ -85,7 +85,7 @@ Once that is done we can drop Multi-Pass Input Iterator.
|
|||||||
<TABLE>
|
<TABLE>
|
||||||
<TR valign=top>
|
<TR valign=top>
|
||||||
<TD nowrap>Copyright © 2000</TD><TD>
|
<TD nowrap>Copyright © 2000</TD><TD>
|
||||||
<A HREF=file:///c:/boost/site/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>
|
</TD></TR></TABLE>
|
||||||
|
|
||||||
</BODY>
|
</BODY>
|
||||||
|
@@ -193,14 +193,14 @@ int main(int argc, char *argv[ ])
|
|||||||
int i = 2;
|
int i = 2;
|
||||||
c2(i);
|
c2(i);
|
||||||
int* pi = &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;
|
call_traits_checker<int*> c3;
|
||||||
c3(pi);
|
c3(pi);
|
||||||
call_traits_checker<int&> c4;
|
call_traits_checker<int&> c4;
|
||||||
c4(i);
|
c4(i);
|
||||||
call_traits_checker<const int&> c5;
|
call_traits_checker<const int&> c5;
|
||||||
c5(i);
|
c5(i);
|
||||||
#if !defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__MWERKS__)
|
#if !defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||||
int a[2] = {1,2};
|
int a[2] = {1,2};
|
||||||
call_traits_checker<int[2]> c6;
|
call_traits_checker<int[2]> c6;
|
||||||
c6(a);
|
c6(a);
|
||||||
@@ -238,7 +238,7 @@ int main(int argc, char *argv[ ])
|
|||||||
type_test(int&, boost::call_traits<int&>::reference)
|
type_test(int&, boost::call_traits<int&>::reference)
|
||||||
type_test(const int&, boost::call_traits<int&>::const_reference)
|
type_test(const int&, boost::call_traits<int&>::const_reference)
|
||||||
type_test(int&, boost::call_traits<int&>::param_type)
|
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>::value_type)
|
||||||
type_test(int&, boost::call_traits<cr_type>::reference)
|
type_test(int&, boost::call_traits<cr_type>::reference)
|
||||||
type_test(const int&, boost::call_traits<cr_type>::const_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
|
#ifdef BOOST_MSVC
|
||||||
unsigned int expected_failures = 10;
|
unsigned int expected_failures = 10;
|
||||||
#elif defined(__SUNPRO_CC)
|
|
||||||
unsigned int expected_failures = 11;
|
|
||||||
#elif defined(__BORLANDC__)
|
#elif defined(__BORLANDC__)
|
||||||
unsigned int expected_failures = 2;
|
unsigned int expected_failures = 2;
|
||||||
#elif defined(__GNUC__)
|
#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">
|
content="text/html; charset=iso-8859-1">
|
||||||
<meta name="Template"
|
<meta name="Template"
|
||||||
content="C:\PROGRAM FILES\MICROSOFT OFFICE\OFFICE\html.dot">
|
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>
|
<title>Header </title>
|
||||||
<boost/compressed_pair.hpp>
|
<boost/compressed_pair.hpp>
|
||||||
</head>
|
</head>
|
||||||
@@ -42,8 +42,6 @@ public:
|
|||||||
explicit compressed_pair(first_param_type x);
|
explicit compressed_pair(first_param_type x);
|
||||||
explicit compressed_pair(second_param_type y);
|
explicit compressed_pair(second_param_type y);
|
||||||
|
|
||||||
compressed_pair& operator=(const compressed_pair&);
|
|
||||||
|
|
||||||
first_reference first();
|
first_reference first();
|
||||||
first_const_reference first() const;
|
first_const_reference first() const;
|
||||||
|
|
||||||
@@ -64,19 +62,17 @@ constructor, and this constructor initialises both values in the
|
|||||||
pair to the passed value.</p>
|
pair to the passed value.</p>
|
||||||
|
|
||||||
<p>Note that compressed_pair can not be instantiated if either of
|
<p>Note that compressed_pair can not be instantiated if either of
|
||||||
the template arguments is a union type, unless there is compiler
|
the template arguments is an enumerator type, unless there is
|
||||||
support for boost::is_union, or if boost::is_union is specialised
|
compiler support for boost::is_enum, or if boost::is_enum is
|
||||||
for the union type.</p>
|
specialised for the enumerator type.</p>
|
||||||
|
|
||||||
<p>Finally, a word of caution for Visual C++ 6 users: if either
|
<p>Finally, compressed_pair requires compiler support for partial
|
||||||
argument is an empty type, then assigning to that member will
|
specialisation of class templates - without that support
|
||||||
produce memory corruption, unless the empty type has a "do
|
compressed_pair behaves just like std::pair.</p>
|
||||||
nothing" assignment operator defined. This is due to a bug
|
|
||||||
in the way VC6 generates implicit assignment operators.</p>
|
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
<p>Revised 08 May 2001</p>
|
<p>Revised 08 March 2000</p>
|
||||||
|
|
||||||
<p><EFBFBD> Copyright boost.org 2000. Permission to copy, use, modify,
|
<p><EFBFBD> Copyright boost.org 2000. Permission to copy, use, modify,
|
||||||
sell and distribute this document is granted provided this
|
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
|
<p>Maintained by <a href="mailto:John_Maddock@compuserve.com">John
|
||||||
Maddock</a>, the latest version of this file can be found at <a
|
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
|
href="http://www.boost.org">www.boost.org</a>, and the boost
|
||||||
discussion list at <a
|
discussion list at <a href="http://www.yahoogroups.com/list/boost">www.yahoogroups.com/list/boost</a>.</p>
|
||||||
href="http://www.yahoogroups.com/list/boost">www.yahoogroups.com/list/boost</a>.</p>
|
|
||||||
|
|
||||||
<p> </p>
|
<p> </p>
|
||||||
</body>
|
</body>
|
||||||
|
@@ -15,8 +15,6 @@
|
|||||||
|
|
||||||
#include <boost/compressed_pair.hpp>
|
#include <boost/compressed_pair.hpp>
|
||||||
#include <boost/type_traits/type_traits_test.hpp>
|
#include <boost/type_traits/type_traits_test.hpp>
|
||||||
#define BOOST_INCLUDE_MAIN
|
|
||||||
#include <boost/test/test_tools.hpp>
|
|
||||||
|
|
||||||
using namespace boost;
|
using namespace boost;
|
||||||
|
|
||||||
@@ -56,346 +54,101 @@ struct non_empty2
|
|||||||
{ return a.i == b.i; }
|
{ return a.i == b.i; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __GNUC__
|
int main(int argc, char *argv[ ])
|
||||||
using std::swap;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template <class T1, class T2>
|
|
||||||
struct compressed_pair_tester
|
|
||||||
{
|
{
|
||||||
// define the types we need:
|
compressed_pair<int, double> cp1(1, 1.3);
|
||||||
typedef T1 first_type;
|
assert(cp1.first() == 1);
|
||||||
typedef T2 second_type;
|
assert(cp1.second() == 1.3);
|
||||||
typedef typename call_traits<first_type>::param_type first_param_type;
|
compressed_pair<int, double> cp1b(2, 2.3);
|
||||||
typedef typename call_traits<second_type>::param_type second_param_type;
|
assert(cp1b.first() == 2);
|
||||||
// define our test proc:
|
assert(cp1b.second() == 2.3);
|
||||||
static void test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4);
|
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>
|
compressed_pair<int, double> cp1e(cp1);
|
||||||
void compressed_pair_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4)
|
|
||||||
{
|
compressed_pair<empty_UDT, int> cp2(2);
|
||||||
#ifndef __GNUC__
|
assert(cp2.second() == 2);
|
||||||
// gcc 2.90 can't cope with function scope using
|
compressed_pair<int, empty_UDT> cp3(1);
|
||||||
// declarations, and generates an internal compiler error...
|
assert(cp3.first() ==1);
|
||||||
using std::swap;
|
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
|
#endif
|
||||||
// default construct:
|
soft_value_test(true, (sizeof(compressed_pair<empty_UDT, int>) < sizeof(std::pair<empty_UDT, int>)))
|
||||||
boost::compressed_pair<T1,T2> cp1;
|
soft_value_test(true, (sizeof(compressed_pair<int, empty_UDT>) < sizeof(std::pair<int, empty_UDT>)))
|
||||||
// first param construct:
|
soft_value_test(true, (sizeof(compressed_pair<empty_UDT, empty_UDT>) < sizeof(std::pair<empty_UDT, empty_UDT>)))
|
||||||
boost::compressed_pair<T1,T2> cp2(p1);
|
soft_value_test(true, (sizeof(compressed_pair<empty_UDT, empty_POD_UDT>) < sizeof(std::pair<empty_UDT, empty_POD_UDT>)))
|
||||||
cp2.second() = p2;
|
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> >)))
|
||||||
BOOST_TEST(cp2.first() == p1);
|
|
||||||
BOOST_TEST(cp2.second() == p2);
|
|
||||||
// second param construct:
|
|
||||||
boost::compressed_pair<T1,T2> cp3(p2);
|
|
||||||
cp3.first() = p1;
|
|
||||||
BOOST_TEST(cp3.second() == p2);
|
|
||||||
BOOST_TEST(cp3.first() == p1);
|
|
||||||
// both param construct:
|
|
||||||
boost::compressed_pair<T1,T2> cp4(p1, p2);
|
|
||||||
BOOST_TEST(cp4.first() == p1);
|
|
||||||
BOOST_TEST(cp4.second() == p2);
|
|
||||||
boost::compressed_pair<T1,T2> cp5(p3, p4);
|
|
||||||
BOOST_TEST(cp5.first() == p3);
|
|
||||||
BOOST_TEST(cp5.second() == p4);
|
|
||||||
// check const members:
|
|
||||||
const boost::compressed_pair<T1,T2>& cpr1 = cp4;
|
|
||||||
BOOST_TEST(cpr1.first() == p1);
|
|
||||||
BOOST_TEST(cpr1.second() == p2);
|
|
||||||
|
|
||||||
// copy construct:
|
return check_result(argc, argv);
|
||||||
boost::compressed_pair<T1,T2> cp6(cp4);
|
|
||||||
BOOST_TEST(cp6.first() == p1);
|
|
||||||
BOOST_TEST(cp6.second() == p2);
|
|
||||||
// assignment:
|
|
||||||
cp1 = cp4;
|
|
||||||
BOOST_TEST(cp1.first() == p1);
|
|
||||||
BOOST_TEST(cp1.second() == p2);
|
|
||||||
cp1 = cp5;
|
|
||||||
BOOST_TEST(cp1.first() == p3);
|
|
||||||
BOOST_TEST(cp1.second() == p4);
|
|
||||||
// swap:
|
|
||||||
cp4.swap(cp5);
|
|
||||||
BOOST_TEST(cp4.first() == p3);
|
|
||||||
BOOST_TEST(cp4.second() == p4);
|
|
||||||
BOOST_TEST(cp5.first() == p1);
|
|
||||||
BOOST_TEST(cp5.second() == p2);
|
|
||||||
swap(cp4,cp5);
|
|
||||||
BOOST_TEST(cp4.first() == p1);
|
|
||||||
BOOST_TEST(cp4.second() == p2);
|
|
||||||
BOOST_TEST(cp5.first() == p3);
|
|
||||||
BOOST_TEST(cp5.second() == p4);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// tests for case where one or both
|
// instanciate some compressed pairs:
|
||||||
// parameters are reference types:
|
#ifdef __MWERKS__
|
||||||
//
|
template class compressed_pair<int, double>;
|
||||||
template <class T1, class T2>
|
template class compressed_pair<int, int>;
|
||||||
struct compressed_pair_reference_tester
|
template class compressed_pair<empty_UDT, int>;
|
||||||
{
|
template class compressed_pair<int, empty_UDT>;
|
||||||
// define the types we need:
|
template class compressed_pair<empty_UDT, empty_UDT>;
|
||||||
typedef T1 first_type;
|
template class compressed_pair<empty_UDT, empty_POD_UDT>;
|
||||||
typedef T2 second_type;
|
#else
|
||||||
typedef typename call_traits<first_type>::param_type first_param_type;
|
template class boost::compressed_pair<int, double>;
|
||||||
typedef typename call_traits<second_type>::param_type second_param_type;
|
template class boost::compressed_pair<int, int>;
|
||||||
// define our test proc:
|
template class boost::compressed_pair<empty_UDT, int>;
|
||||||
static void test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4);
|
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>;
|
||||||
template <class T1, class T2>
|
|
||||||
void compressed_pair_reference_tester<T1, T2>::test(first_param_type p1, second_param_type p2, first_param_type p3, second_param_type p4)
|
|
||||||
{
|
|
||||||
#ifndef __GNUC__
|
|
||||||
// gcc 2.90 can't cope with function scope using
|
|
||||||
// declarations, and generates an internal compiler error...
|
|
||||||
using std::swap;
|
|
||||||
#endif
|
#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
|
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
// first param construct:
|
#ifndef __MWERKS__
|
||||||
boost::compressed_pair<T1,T2> cp2(p1);
|
//
|
||||||
cp2.second() = p2;
|
// now some for which only a few specific members can be instantiated,
|
||||||
BOOST_TEST(cp2.first() == p1);
|
// first references:
|
||||||
BOOST_TEST(cp2.second() == p2);
|
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
|
#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:
|
// and then arrays:
|
||||||
//
|
#ifndef __BORLANDC__
|
||||||
template <class T1, class T2>
|
template call_traits<int[2]>::reference compressed_pair<double, int[2]>::second();
|
||||||
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);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
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);
|
||||||
// tests for where one or the other parameter is an array:
|
#endif
|
||||||
//
|
template compressed_pair<double, int[2]>::compressed_pair();
|
||||||
template <class T1, class T2>
|
#endif // __MWERKS__
|
||||||
struct compressed_pair_array1_tester
|
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
{
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
unsigned int expected_failures = 0;
|
unsigned int expected_failures = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1,23 +1,20 @@
|
|||||||
// Boost operators.hpp header file ----------------------------------------//
|
// Boost operators.hpp header file ----------------------------------------//
|
||||||
|
|
||||||
// (C) Copyright David Abrahams, Jeremy Siek, and Daryle Walker 1999-2001.
|
// (C) Copyright David Abrahams 1999. Permission to copy, use,
|
||||||
// Permission to copy, use, modify, sell and distribute this software is
|
// modify, sell and distribute this software is granted provided this
|
||||||
// granted provided this copyright notice appears in all copies. This
|
// copyright notice appears in all copies. This software is provided
|
||||||
// software is provided "as is" without express or implied warranty, and
|
// "as is" without express or implied warranty, and with no claim as
|
||||||
// with no claim as to its suitability for any purpose.
|
// 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.
|
// See http://www.boost.org for most recent version including documentation.
|
||||||
|
|
||||||
// Revision History
|
// 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
|
// 11 Feb 01 Fixed bugs in the iterator helpers which prevented explicitly
|
||||||
// supplied arguments from actually being used (Dave Abrahams)
|
// supplied arguments from actually being used (Dave Abrahams)
|
||||||
// 04 Jul 00 Fixed NO_OPERATORS_IN_NAMESPACE bugs, major cleanup and
|
// 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
|
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
#endif // BOOST_NO_OPERATORS_IN_NAMESPACE
|
#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
|
// 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
|
// 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
|
// two-argument forms. Note that these macros expect to be invoked from within
|
||||||
// boost.
|
// 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.
|
# if defined(BOOST_NO_USING_TEMPLATE)
|
||||||
# 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> {};
|
|
||||||
|
|
||||||
|
// 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) \
|
# define BOOST_IMPORT_TEMPLATE2(template_name) \
|
||||||
template <class T, class U, class B = ::boost::detail::empty_base> \
|
template <class T, class U, class B = ::boost::detail::empty_base> \
|
||||||
struct template_name : ::template_name<T, U, B> {};
|
struct template_name : ::template_name<T, U, B> {};
|
||||||
@@ -509,8 +309,21 @@ struct shiftable1
|
|||||||
template <class T, class B = ::boost::detail::empty_base> \
|
template <class T, class B = ::boost::detail::empty_base> \
|
||||||
struct template_name : ::template_name<T, B> {};
|
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
|
# 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
|
#endif // BOOST_NO_OPERATORS_IN_NAMESPACE
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -519,7 +332,7 @@ struct shiftable1
|
|||||||
// the xxxx, xxxx1, and xxxx2 templates, importing them into boost:: as
|
// the xxxx, xxxx1, and xxxx2 templates, importing them into boost:: as
|
||||||
// neccessary.
|
// 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
|
// 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
|
// 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
|
} // 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
|
// Import a 2-type-argument operator template into boost (if neccessary) and
|
||||||
// provide a specialization of 'is_chained_base<>' for it.
|
// provide a specialization of 'is_chained_base<>' for it.
|
||||||
# define BOOST_OPERATOR_TEMPLATE2(template_name2) \
|
# define BOOST_OPERATOR_TEMPLATE2(template_name2) \
|
||||||
@@ -610,8 +414,6 @@ BOOST_OPERATOR_TEMPLATE1(template_name##1)
|
|||||||
|
|
||||||
#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
|
|
||||||
# define BOOST_OPERATOR_TEMPLATE3(template_name3) \
|
|
||||||
BOOST_IMPORT_TEMPLATE3(template_name3)
|
|
||||||
# define BOOST_OPERATOR_TEMPLATE2(template_name2) \
|
# define BOOST_OPERATOR_TEMPLATE2(template_name2) \
|
||||||
BOOST_IMPORT_TEMPLATE2(template_name2)
|
BOOST_IMPORT_TEMPLATE2(template_name2)
|
||||||
# define BOOST_OPERATOR_TEMPLATE1(template_name1) \
|
# define BOOST_OPERATOR_TEMPLATE1(template_name1) \
|
||||||
@@ -640,41 +442,47 @@ BOOST_OPERATOR_TEMPLATE(orable)
|
|||||||
|
|
||||||
BOOST_OPERATOR_TEMPLATE1(incrementable)
|
BOOST_OPERATOR_TEMPLATE1(incrementable)
|
||||||
BOOST_OPERATOR_TEMPLATE1(decrementable)
|
BOOST_OPERATOR_TEMPLATE1(decrementable)
|
||||||
|
|
||||||
BOOST_OPERATOR_TEMPLATE2(dereferenceable)
|
BOOST_OPERATOR_TEMPLATE2(dereferenceable)
|
||||||
BOOST_OPERATOR_TEMPLATE3(indexable)
|
|
||||||
|
|
||||||
BOOST_OPERATOR_TEMPLATE(left_shiftable)
|
// indexable doesn't follow the patterns above (it has 4 template arguments), so
|
||||||
BOOST_OPERATOR_TEMPLATE(right_shiftable)
|
// we just write out the compiler hacks explicitly.
|
||||||
BOOST_OPERATOR_TEMPLATE(equivalent)
|
#ifdef BOOST_NO_OPERATORS_IN_NAMESPACE
|
||||||
BOOST_OPERATOR_TEMPLATE(partially_ordered)
|
# 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)
|
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
BOOST_OPERATOR_TEMPLATE(additive)
|
template <class T, class I, class R, class B>
|
||||||
BOOST_OPERATOR_TEMPLATE(multiplicative)
|
struct is_chained_base< ::boost::indexable<T, I, R, B> > {
|
||||||
BOOST_OPERATOR_TEMPLATE(integer_multiplicative)
|
typedef ::boost::detail::true_t operator_template_type;
|
||||||
BOOST_OPERATOR_TEMPLATE(arithmetic)
|
};
|
||||||
BOOST_OPERATOR_TEMPLATE(integer_arithmetic)
|
#endif
|
||||||
BOOST_OPERATOR_TEMPLATE(bitwise)
|
|
||||||
BOOST_OPERATOR_TEMPLATE1(unit_steppable)
|
|
||||||
BOOST_OPERATOR_TEMPLATE(shiftable)
|
|
||||||
|
|
||||||
#undef BOOST_OPERATOR_TEMPLATE
|
#undef BOOST_OPERATOR_TEMPLATE
|
||||||
#undef BOOST_OPERATOR_TEMPLATE3
|
|
||||||
#undef BOOST_OPERATOR_TEMPLATE2
|
#undef BOOST_OPERATOR_TEMPLATE2
|
||||||
#undef BOOST_OPERATOR_TEMPLATE1
|
#undef BOOST_OPERATOR_TEMPLATE1
|
||||||
#undef BOOST_IMPORT_TEMPLATE1
|
#undef BOOST_IMPORT_TEMPLATE1
|
||||||
#undef BOOST_IMPORT_TEMPLATE2
|
#undef BOOST_IMPORT_TEMPLATE2
|
||||||
#undef BOOST_IMPORT_TEMPLATE3
|
|
||||||
|
|
||||||
// The following 'operators' classes can only be used portably if the derived class
|
// The following 'operators' classes can only be used portably if the derived class
|
||||||
// declares ALL of the required member operators.
|
// declares ALL of the required member operators.
|
||||||
template <class T, class U>
|
template <class T, class U>
|
||||||
struct operators2
|
struct operators2
|
||||||
: totally_ordered2<T,U
|
: less_than_comparable2<T,U
|
||||||
, integer_arithmetic2<T,U
|
, equality_comparable2<T,U
|
||||||
, bitwise2<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
|
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
template <class T, class U = T>
|
template <class T, class U = T>
|
||||||
@@ -684,47 +492,31 @@ template <class T> struct operators<T, T>
|
|||||||
#else
|
#else
|
||||||
template <class T> struct operators
|
template <class T> struct operators
|
||||||
#endif
|
#endif
|
||||||
: totally_ordered<T
|
: less_than_comparable<T
|
||||||
, integer_arithmetic<T
|
, equality_comparable<T
|
||||||
, bitwise<T
|
, addable<T
|
||||||
, unit_steppable<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) -------------------//
|
// 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,
|
template <class T,
|
||||||
class V,
|
class V,
|
||||||
class D = std::ptrdiff_t,
|
class D = std::ptrdiff_t,
|
||||||
class P = V*,
|
class P = V*,
|
||||||
class R = V&>
|
class R = V&>
|
||||||
struct forward_iterator_helper
|
struct forward_iterator_helper
|
||||||
: equality_comparable1<T
|
: equality_comparable<T
|
||||||
, incrementable<T
|
, incrementable<T
|
||||||
, dereferenceable<T, P
|
, dereferenceable<T,P
|
||||||
, boost::iterator<std::forward_iterator_tag, V, D, P, R
|
, boost::iterator<std::forward_iterator_tag,V,D,P,R
|
||||||
> > > > {};
|
> > > > {};
|
||||||
|
|
||||||
template <class T,
|
template <class T,
|
||||||
@@ -733,11 +525,12 @@ template <class T,
|
|||||||
class P = V*,
|
class P = V*,
|
||||||
class R = V&>
|
class R = V&>
|
||||||
struct bidirectional_iterator_helper
|
struct bidirectional_iterator_helper
|
||||||
: equality_comparable1<T
|
: equality_comparable<T
|
||||||
, unit_steppable<T
|
, incrementable<T
|
||||||
, dereferenceable<T, P
|
, decrementable<T
|
||||||
, boost::iterator<std::bidirectional_iterator_tag, V, D, P, R
|
, dereferenceable<T,P
|
||||||
> > > > {};
|
, boost::iterator<std::bidirectional_iterator_tag,V,D,P,R
|
||||||
|
> > > > > {};
|
||||||
|
|
||||||
template <class T,
|
template <class T,
|
||||||
class V,
|
class V,
|
||||||
@@ -745,17 +538,22 @@ template <class T,
|
|||||||
class P = V*,
|
class P = V*,
|
||||||
class R = V&>
|
class R = V&>
|
||||||
struct random_access_iterator_helper
|
struct random_access_iterator_helper
|
||||||
: totally_ordered1<T
|
: equality_comparable<T
|
||||||
, unit_steppable<T
|
, less_than_comparable<T
|
||||||
, dereferenceable<T, P
|
, incrementable<T
|
||||||
, additive2<T, D
|
, decrementable<T
|
||||||
, indexable<T, D, R
|
, dereferenceable<T,P
|
||||||
, boost::iterator<std::random_access_iterator_tag, V, D, P, R
|
, 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) {
|
friend D requires_difference_operator(const T& x, const T& y) {
|
||||||
return x - y;
|
return x - y;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}; // random_access_iterator_helper
|
}; // random_access_iterator_helper
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
@@ -11,9 +11,6 @@
|
|||||||
// Classes appear in alphabetical order
|
// Classes appear in alphabetical order
|
||||||
|
|
||||||
// Revision History
|
// 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)
|
// 26 Jan 00 protected noncopyable destructor added (Miki Jovanovic)
|
||||||
// 10 Dec 99 next() and prior() templates added (Dave Abrahams)
|
// 10 Dec 99 next() and prior() templates added (Dave Abrahams)
|
||||||
// 30 Aug 99 moved cast templates to cast.hpp (Beman Dawes)
|
// 30 Aug 99 moved cast templates to cast.hpp (Beman Dawes)
|
||||||
@@ -25,32 +22,12 @@
|
|||||||
#ifndef BOOST_UTILITY_HPP
|
#ifndef BOOST_UTILITY_HPP
|
||||||
#define BOOST_UTILITY_HPP
|
#define BOOST_UTILITY_HPP
|
||||||
|
|
||||||
#include <boost/config.hpp> // broken compiler workarounds
|
#include <boost/config.hpp>
|
||||||
#include <boost/static_assert.hpp>
|
#include <cstddef> // for size_t
|
||||||
#include <cstddef> // for size_t
|
#include <utility> // for std::pair
|
||||||
#include <utility> // for std::pair
|
|
||||||
|
|
||||||
namespace boost
|
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 -----------------------------------//
|
// next() and prior() template functions -----------------------------------//
|
||||||
|
|
||||||
@@ -64,10 +41,10 @@ namespace boost
|
|||||||
// Contributed by Dave Abrahams
|
// Contributed by Dave Abrahams
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
inline T next(T x) { return ++x; }
|
T next(T x) { return ++x; }
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
inline T prior(T x) { return --x; }
|
T prior(T x) { return --x; }
|
||||||
|
|
||||||
|
|
||||||
// class noncopyable -------------------------------------------------------//
|
// class noncopyable -------------------------------------------------------//
|
||||||
|
@@ -29,7 +29,8 @@ int main(int, char*[])
|
|||||||
|
|
||||||
// Example of using indirect_iterator_pair_generator
|
// 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 mutable_characters[N];
|
||||||
char* pointers_to_mutable_chars[N];
|
char* pointers_to_mutable_chars[N];
|
||||||
|
@@ -93,7 +93,7 @@
|
|||||||
<a href="function_output_iterator.htm">Function Output Iterator Adaptor</a>
|
<a href="function_output_iterator.htm">Function Output Iterator Adaptor</a>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p><b><a href="file:///c:/boost/site/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=
|
Abrahams</a></b> started the library, applying <a href=
|
||||||
"../../more/generic_programming.html#policy">policy class</a> technique and
|
"../../more/generic_programming.html#policy">policy class</a> technique and
|
||||||
handling const/non-const iterator interactions. He also contributed the
|
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
|
<tt><a href="counting_iterator.htm">counting_iterator_generator</a></tt> to
|
||||||
cover all incrementable types. He edited most of the documentation,
|
cover all incrementable types. He edited most of the documentation,
|
||||||
sometimes heavily.<br>
|
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
|
Siek</a></b> contributed the <a href="transform_iterator.htm">transform
|
||||||
iterator</a> adaptor, the integer-only version of <tt><a href=
|
iterator</a> adaptor, the integer-only version of <tt><a href=
|
||||||
"counting_iterator.htm">counting_iterator_generator</a></tt>,
|
"counting_iterator.htm">counting_iterator_generator</a></tt>,
|
||||||
@@ -860,7 +860,7 @@ bool operator==(const iterator_adaptor<B1,P,V1,R1,P1,C,D>&,
|
|||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
<p>Revised
|
<p>Revised
|
||||||
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->12 Jul 2001<!--webbot bot="Timestamp" endspan i-checksum="14985" -->
|
<!--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,
|
<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.
|
// See http://www.boost.org for most recent version including documentation.
|
||||||
|
|
||||||
// Revision History
|
// 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)
|
// 12 Dec 99 Initial version with iterator operators (Jeremy Siek)
|
||||||
|
|
||||||
#define BOOST_INCLUDE_MAIN
|
#include <string>
|
||||||
#include <boost/test/test_tools.hpp> // for main
|
#include <iostream>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
#include <boost/config.hpp> // for BOOST_STATIC_CONSTANT
|
#include <boost/operators.hpp>
|
||||||
#include <boost/cstdlib.hpp> // for boost::exit_success
|
using namespace boost;
|
||||||
#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
|
|
||||||
|
|
||||||
|
|
||||||
// Iterator test class
|
|
||||||
template <class T, class R, class P>
|
template <class T, class R, class P>
|
||||||
struct test_iter
|
struct test_iter
|
||||||
: public boost::random_access_iterator_helper<
|
: public boost::random_access_iterator_helper<
|
||||||
@@ -42,7 +29,7 @@ struct test_iter
|
|||||||
typedef std::ptrdiff_t Distance;
|
typedef std::ptrdiff_t Distance;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit test_iter(T* i =0) : _i(i) { }
|
test_iter(T* i) : _i(i) { }
|
||||||
test_iter(const self& x) : _i(x._i) { }
|
test_iter(const self& x) : _i(x._i) { }
|
||||||
self& operator=(const self& x) { _i = x._i; return *this; }
|
self& operator=(const self& x) { _i = x._i; return *this; }
|
||||||
Reference operator*() const { return *_i; }
|
Reference operator*() const { return *_i; }
|
||||||
@@ -56,280 +43,127 @@ public:
|
|||||||
return x._i - y._i;
|
return x._i - y._i;
|
||||||
}
|
}
|
||||||
protected:
|
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
|
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;
|
// Tests for all of the operators added by random_access_iterator_helper
|
||||||
typedef test_opr<string, string const &, string const *> test2_type;
|
|
||||||
|
|
||||||
test1_type::master_test( "non-const string" );
|
// test i++
|
||||||
test2_type::master_test( "const string" );
|
while (i != ie)
|
||||||
|
cout << *i++ << " ";
|
||||||
|
cout << endl;
|
||||||
|
i = array;
|
||||||
|
|
||||||
return boost::exit_success;
|
// test i--
|
||||||
}
|
while (ie != i) {
|
||||||
|
ie--;
|
||||||
// Tests for all of the operators added by random_access_iterator_helper
|
cout << *ie << " ";
|
||||||
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++ << ' ';
|
|
||||||
}
|
}
|
||||||
|
cout << endl;
|
||||||
|
ie = array + sizeof(array)/sizeof(string);
|
||||||
|
|
||||||
oss << std::ends;
|
// test i->m
|
||||||
BOOST_TEST( std::strcmp(oss.str(), "apple orange pear peach grape plum ")
|
while (i != ie) {
|
||||||
== 0 );
|
cout << i->size() << " ";
|
||||||
}
|
++i;
|
||||||
|
|
||||||
// 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 << ' ';
|
|
||||||
}
|
}
|
||||||
|
cout << endl;
|
||||||
|
i = array;
|
||||||
|
|
||||||
oss << std::ends;
|
// test i + n
|
||||||
BOOST_TEST( std::strcmp(oss.str(), "plum grape peach pear orange apple ")
|
while (i < ie) {
|
||||||
== 0 );
|
cout << *i << " ";
|
||||||
}
|
i = i + 2;
|
||||||
|
|
||||||
// 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() << ' ';
|
|
||||||
}
|
}
|
||||||
|
cout << endl;
|
||||||
|
i = array;
|
||||||
|
|
||||||
oss << std::ends;
|
// test n + i
|
||||||
BOOST_TEST( std::strcmp(oss.str(), "5 6 4 5 5 4 ") == 0 );
|
while (i < ie) {
|
||||||
}
|
cout << *i << " ";
|
||||||
|
i = ptrdiff_t(2) + i;
|
||||||
// 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 << ' ';
|
|
||||||
}
|
}
|
||||||
|
cout << endl;
|
||||||
|
i = array;
|
||||||
|
|
||||||
oss << std::ends;
|
// test i - n
|
||||||
BOOST_TEST( std::strcmp(oss.str(), "apple pear grape ") == 0 );
|
while (ie > i) {
|
||||||
}
|
ie = ie - 2;
|
||||||
|
cout << *ie << " ";
|
||||||
// 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 << ' ';
|
|
||||||
}
|
}
|
||||||
|
cout << endl;
|
||||||
|
ie = array + sizeof(array)/sizeof(string);
|
||||||
|
|
||||||
oss << std::ends;
|
// test i[n]
|
||||||
BOOST_TEST( std::strcmp(oss.str(), "apple pear grape ") == 0 );
|
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
|
// 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>::offset_subtraction_test
|
|
||||||
(
|
|
||||||
)
|
|
||||||
{
|
|
||||||
std::cout << "\tDoing offset subtraction test." << std::endl;
|
|
||||||
|
|
||||||
std::ptrdiff_t const two = 2;
|
// test i++
|
||||||
std::ostrstream oss( scratch, scratch_length );
|
while (i != ie)
|
||||||
for ( iter_type i = fruit_end ; fruit_begin < i ; )
|
cout << *i++ << " ";
|
||||||
{
|
cout << endl;
|
||||||
i = i - two;
|
i = array;
|
||||||
if ( (fruit_begin < i) || (fruit_begin == i) )
|
|
||||||
{
|
// test i--
|
||||||
oss << *i << ' ';
|
while (ie != i) {
|
||||||
}
|
ie--;
|
||||||
|
cout << *ie << " ";
|
||||||
}
|
}
|
||||||
|
cout << endl;
|
||||||
|
ie = array + sizeof(array)/sizeof(string);
|
||||||
|
|
||||||
oss << std::ends;
|
// test i->m
|
||||||
BOOST_TEST( std::strcmp(oss.str(), "grape pear apple ") == 0 );
|
while (i != ie) {
|
||||||
}
|
cout << i->size() << " ";
|
||||||
|
++i;
|
||||||
// Test comparisons
|
|
||||||
template <typename T, typename R, typename P>
|
|
||||||
void
|
|
||||||
test_opr<T, R, P>::comparison_test
|
|
||||||
(
|
|
||||||
)
|
|
||||||
{
|
|
||||||
using std::cout;
|
|
||||||
using std::ptrdiff_t;
|
|
||||||
|
|
||||||
cout << "\tDoing comparison tests.\n\t\tPass:";
|
|
||||||
|
|
||||||
for ( iter_type i = fruit_begin ; i != fruit_end ; ++i )
|
|
||||||
{
|
|
||||||
ptrdiff_t const i_offset = i - fruit_begin;
|
|
||||||
|
|
||||||
cout << ' ' << *i << std::flush;
|
|
||||||
for ( iter_type j = fruit_begin ; j != fruit_end ; ++j )
|
|
||||||
{
|
|
||||||
ptrdiff_t const j_offset = j - fruit_begin;
|
|
||||||
|
|
||||||
BOOST_TEST( (i != j) == (i_offset != j_offset) );
|
|
||||||
BOOST_TEST( (i > j) == (i_offset > j_offset) );
|
|
||||||
BOOST_TEST( (i <= j) == (i_offset <= j_offset) );
|
|
||||||
BOOST_TEST( (i >= j) == (i_offset >= j_offset) );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
cout << std::endl;
|
cout << endl;
|
||||||
}
|
i = array;
|
||||||
|
|
||||||
// Test indexing
|
// test i + n
|
||||||
template <typename T, typename R, typename P>
|
while (i < ie) {
|
||||||
void
|
cout << *i << " ";
|
||||||
test_opr<T, R, P>::indexing_test
|
i = i + 2;
|
||||||
(
|
|
||||||
)
|
|
||||||
{
|
|
||||||
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 ] << ' ';
|
|
||||||
}
|
}
|
||||||
|
cout << endl;
|
||||||
|
i = array;
|
||||||
|
|
||||||
oss << std::ends;
|
// test n + i
|
||||||
BOOST_TEST( std::strcmp(oss.str(), "apple orange pear peach grape plum ")
|
while (i < ie) {
|
||||||
== 0 );
|
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.
|
// See http://www.boost.org for most recent version including documentation.
|
||||||
|
|
||||||
// Revision History
|
// Revision History
|
||||||
// 1 Apr 2001 Fixes for ICL; use BOOST_STATIC_CONSTANT
|
|
||||||
// 11 Feb 2001 Fixes for Borland (David Abrahams)
|
// 11 Feb 2001 Fixes for Borland (David Abrahams)
|
||||||
// 23 Jan 2001 Added test for wchar_t (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
|
// 23 Jan 2001 Now statically selecting a test for signed numbers to avoid
|
||||||
@@ -31,6 +30,13 @@
|
|||||||
# include <limits>
|
# include <limits>
|
||||||
#endif
|
#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> --
|
// template class complement_traits<Number> --
|
||||||
//
|
//
|
||||||
@@ -47,8 +53,8 @@ template <unsigned size> struct complement; // forward
|
|||||||
template <class Number, unsigned size>
|
template <class Number, unsigned size>
|
||||||
struct complement_traits_aux
|
struct complement_traits_aux
|
||||||
{
|
{
|
||||||
BOOST_STATIC_CONSTANT(Number, max = complement<size>::template traits<Number>::max);
|
DECLARE_CLASS_CONST(Number, max = complement<size>::template traits<Number>::max);
|
||||||
BOOST_STATIC_CONSTANT(Number, min = complement<size>::template traits<Number>::min);
|
DECLARE_CLASS_CONST(Number, min = complement<size>::template traits<Number>::min);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <unsigned size>
|
template <unsigned size>
|
||||||
@@ -61,11 +67,11 @@ struct complement
|
|||||||
// indirection through complement_traits_aux neccessary to keep MSVC happy
|
// indirection through complement_traits_aux neccessary to keep MSVC happy
|
||||||
typedef complement_traits_aux<Number, size - 1> prev;
|
typedef complement_traits_aux<Number, size - 1> prev;
|
||||||
public:
|
public:
|
||||||
BOOST_STATIC_CONSTANT(Number, max =
|
DECLARE_CLASS_CONST(Number, max =
|
||||||
Number(Number(prev::max) << CHAR_BIT)
|
Number(Number(prev::max) << CHAR_BIT)
|
||||||
+ Number(UCHAR_MAX));
|
+ 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>
|
template <class Number>
|
||||||
struct values
|
struct values
|
||||||
{
|
{
|
||||||
BOOST_STATIC_CONSTANT(Number, min = 0);
|
DECLARE_CLASS_CONST(Number, min = 0);
|
||||||
BOOST_STATIC_CONSTANT(Number, max = UCHAR_MAX);
|
DECLARE_CLASS_CONST(Number, max = UCHAR_MAX);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -89,8 +95,8 @@ template <> struct complement_base<true>
|
|||||||
template <class Number>
|
template <class Number>
|
||||||
struct values
|
struct values
|
||||||
{
|
{
|
||||||
BOOST_STATIC_CONSTANT(Number, min = SCHAR_MIN);
|
DECLARE_CLASS_CONST(Number, min = SCHAR_MIN);
|
||||||
BOOST_STATIC_CONSTANT(Number, max = SCHAR_MAX);
|
DECLARE_CLASS_CONST(Number, max = SCHAR_MAX);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -101,10 +107,10 @@ struct complement<1>
|
|||||||
template <class Number>
|
template <class Number>
|
||||||
struct traits
|
struct traits
|
||||||
{
|
{
|
||||||
BOOST_STATIC_CONSTANT(bool, is_signed = boost::detail::is_signed<Number>::value);
|
DECLARE_CLASS_CONST(bool, is_signed = boost::detail::is_signed<Number>::value);
|
||||||
BOOST_STATIC_CONSTANT(Number, min =
|
DECLARE_CLASS_CONST(Number, min =
|
||||||
complement_base<is_signed>::template values<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);
|
complement_base<is_signed>::template values<Number>::max);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -115,8 +121,8 @@ struct complement<1>
|
|||||||
template <class Number>
|
template <class Number>
|
||||||
struct complement_traits
|
struct complement_traits
|
||||||
{
|
{
|
||||||
BOOST_STATIC_CONSTANT(Number, max = (complement_traits_aux<Number, sizeof(Number)>::max));
|
DECLARE_CLASS_CONST(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, 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;
|
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> {
|
template <> struct stream_as<boost::uintmax_t> {
|
||||||
typedef std::string t1;
|
typedef std::string t1;
|
||||||
typedef std::string t2;
|
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.
|
// On this platform, stream them as long/unsigned long if they fit.
|
||||||
// Otherwise, write a string.
|
// 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.
|
// See http://www.boost.org for most recent version including documentation.
|
||||||
|
|
||||||
// Revision History
|
// 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)
|
// 04 Jun 00 Added regression test for a bug I found (David Abrahams)
|
||||||
// 17 Jun 00 Fix for broken compilers (Aleksey Gurtovoy)
|
// 17 Jun 00 Fix for broken compilers (Aleksey Gurtovoy)
|
||||||
// ?? ??? 00 Major update to randomly test all one- and two- argument forms by
|
// ?? ??? 00 Major update to randomly test all one- and two- argument forms by
|
||||||
// wrapping integral types and comparing the results of operations
|
// wrapping integral types and comparing the results of operations to
|
||||||
// to the results for the raw types (David Abrahams)
|
// the results for the raw types (David Abrahams)
|
||||||
// 12 Dec 99 Minor update, output confirmation message.
|
// 12 Dec 99 Minor update, output confirmation message.
|
||||||
// 15 Nov 99 Initial version
|
// 15 Nov 99 Initial version
|
||||||
|
|
||||||
#define BOOST_INCLUDE_MAIN
|
#include <boost/operators.hpp>
|
||||||
|
#include <cassert>
|
||||||
#include <boost/config.hpp> // for BOOST_MSVC
|
#include <iostream>
|
||||||
#include <boost/cstdlib.hpp> // for boost::exit_success
|
#include <boost/min_rand.hpp>
|
||||||
#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)
|
|
||||||
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
@@ -36,18 +28,14 @@ namespace
|
|||||||
int true_value(int x) { return x; }
|
int true_value(int x) { return x; }
|
||||||
long true_value(long x) { return x; }
|
long true_value(long x) { return x; }
|
||||||
signed char true_value(signed char 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 int true_value(unsigned int x) { return x; }
|
||||||
unsigned long true_value(unsigned long x) { return x; }
|
unsigned long true_value(unsigned long x) { return x; }
|
||||||
unsigned char true_value(unsigned char 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
|
// The use of operators<> here tended to obscure interactions with certain
|
||||||
// interactions with certain compiler bugs
|
// compiler bugs
|
||||||
template <class T>
|
template <class T>
|
||||||
class Wrapped1
|
class Wrapped1 : boost::operators<Wrapped1<T> >
|
||||||
: boost::operators<Wrapped1<T> >
|
|
||||||
, boost::shiftable<Wrapped1<T> >
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit Wrapped1( T v = T() ) : _value(v) {}
|
explicit Wrapped1( T v = T() ) : _value(v) {}
|
||||||
@@ -72,10 +60,6 @@ namespace
|
|||||||
{ _value &= x._value; return *this; }
|
{ _value &= x._value; return *this; }
|
||||||
Wrapped1& operator^=(const Wrapped1& x)
|
Wrapped1& operator^=(const Wrapped1& x)
|
||||||
{ _value ^= x._value; return *this; }
|
{ _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; }
|
||||||
Wrapped1& operator--() { --_value; return *this; }
|
Wrapped1& operator--() { --_value; return *this; }
|
||||||
|
|
||||||
@@ -86,11 +70,9 @@ namespace
|
|||||||
T true_value(Wrapped1<T> x) { return x.value(); }
|
T true_value(Wrapped1<T> x) { return x.value(); }
|
||||||
|
|
||||||
template <class T, class U>
|
template <class T, class U>
|
||||||
class Wrapped2
|
class Wrapped2 :
|
||||||
: boost::operators<Wrapped2<T, U> >
|
boost::operators<Wrapped2<T, U> >,
|
||||||
, boost::operators2<Wrapped2<T, U>, U>
|
boost::operators2<Wrapped2<T, U>, U>
|
||||||
, boost::shiftable1<Wrapped2<T, U>
|
|
||||||
, boost::shiftable2<Wrapped2<T, U>, U > >
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit Wrapped2( T v = T() ) : _value(v) {}
|
explicit Wrapped2( T v = T() ) : _value(v) {}
|
||||||
@@ -115,10 +97,6 @@ namespace
|
|||||||
{ _value &= x._value; return *this; }
|
{ _value &= x._value; return *this; }
|
||||||
Wrapped2& operator^=(const Wrapped2& x)
|
Wrapped2& operator^=(const Wrapped2& x)
|
||||||
{ _value ^= x._value; return *this; }
|
{ _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; }
|
||||||
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; }
|
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:
|
private:
|
||||||
T _value;
|
T _value;
|
||||||
@@ -142,268 +118,203 @@ namespace
|
|||||||
template <class T, class U>
|
template <class T, class U>
|
||||||
T true_value(Wrapped2<T,U> x) { return x.value(); }
|
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<>
|
// MyInt uses only the single template-argument form of all_operators<>
|
||||||
typedef Wrapped1<int> MyInt;
|
typedef Wrapped1<int> MyInt;
|
||||||
|
|
||||||
typedef Wrapped2<long, long> MyLong;
|
typedef Wrapped2<long, long> MyLong;
|
||||||
|
|
||||||
typedef Wrapped3<signed char> MyChar;
|
|
||||||
|
|
||||||
typedef Wrapped4<short, short> MyShort;
|
|
||||||
|
|
||||||
template <class X1, class Y1, class X2, class Y2>
|
template <class X1, class Y1, class X2, class Y2>
|
||||||
void sanity_check(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
void sanity_check(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
||||||
{
|
{
|
||||||
BOOST_TEST( true_value(y1) == true_value(y2) );
|
assert(true_value(y1) == true_value(y2));
|
||||||
BOOST_TEST( true_value(x1) == true_value(x2) );
|
assert(true_value(x1) == true_value(x2));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class X1, class Y1, class X2, class Y2>
|
template <class X1, class Y1, class X2, class Y2>
|
||||||
void test_less_than_comparable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
void test_less_than_comparable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
||||||
{
|
{
|
||||||
BOOST_TEST( (x1 < y1) == (x2 < y2) );
|
assert((x1 < y1) == (x2 < y2));
|
||||||
BOOST_TEST( (x1 <= y1) == (x2 <= y2) );
|
assert((x1 <= y1) == (x2 <= y2));
|
||||||
BOOST_TEST( (x1 >= y1) == (x2 >= y2) );
|
assert((x1 >= y1) == (x2 >= y2));
|
||||||
BOOST_TEST( (x1 > y1) == (x2 > y2) );
|
assert((x1 > y1) == (x2 > y2));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class X1, class Y1, class X2, class Y2>
|
template <class X1, class Y1, class X2, class Y2>
|
||||||
void test_less_than_comparable(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
void test_less_than_comparable(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
||||||
{
|
{
|
||||||
sanity_check( x1, y1, x2, y2 );
|
sanity_check(x1, y1, x2, y2);
|
||||||
test_less_than_comparable_aux( x1, y1, x2, y2 );
|
test_less_than_comparable_aux(x1, y1, x2, y2);
|
||||||
test_less_than_comparable_aux( y1, x1, y2, x2 );
|
test_less_than_comparable_aux(y1, x1, y2, x2);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class X1, class Y1, class X2, class Y2>
|
template <class X1, class Y1, class X2, class Y2>
|
||||||
void test_equality_comparable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
void test_equality_comparable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
||||||
{
|
{
|
||||||
BOOST_TEST( (x1 == y1) == (x2 == y2) );
|
assert((x1 == y1) == (x2 == y2));
|
||||||
BOOST_TEST( (x1 != y1) == (x2 != y2) );
|
assert((x1 != y1) == (x2 != y2));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class X1, class Y1, class X2, class Y2>
|
template <class X1, class Y1, class X2, class Y2>
|
||||||
void test_equality_comparable(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
void test_equality_comparable(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
||||||
{
|
{
|
||||||
sanity_check( x1, y1, x2, y2 );
|
sanity_check(x1, y1, x2, y2);
|
||||||
test_equality_comparable_aux( x1, y1, x2, y2 );
|
test_equality_comparable_aux(x1, y1, x2, y2);
|
||||||
test_equality_comparable_aux( y1, x1, y2, x2 );
|
test_equality_comparable_aux(y1, x1, y2, x2);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class X1, class Y1, class X2, class Y2>
|
template <class X1, class Y1, class X2, class Y2>
|
||||||
void test_multipliable_aux(X1 x1, Y1 y1, X2 x2, Y2 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>
|
template <class X1, class Y1, class X2, class Y2>
|
||||||
void test_multipliable(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
void test_multipliable(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
||||||
{
|
{
|
||||||
sanity_check( x1, y1, x2, y2 );
|
sanity_check(x1, y1, x2, y2);
|
||||||
test_multipliable_aux( x1, y1, x2, y2 );
|
test_multipliable_aux(x1, y1, x2, y2);
|
||||||
test_multipliable_aux( y1, x1, y2, x2 );
|
test_multipliable_aux(y1, x1, y2, x2);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class X1, class Y1, class X2, class Y2>
|
template <class X1, class Y1, class X2, class Y2>
|
||||||
void test_addable_aux(X1 x1, Y1 y1, X2 x2, Y2 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>
|
template <class X1, class Y1, class X2, class Y2>
|
||||||
void test_addable(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
void test_addable(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
||||||
{
|
{
|
||||||
sanity_check( x1, y1, x2, y2 );
|
sanity_check(x1, y1, x2, y2);
|
||||||
test_addable_aux( x1, y1, x2, y2 );
|
test_addable_aux(x1, y1, x2, y2);
|
||||||
test_addable_aux( y1, x1, y2, x2 );
|
test_addable_aux(y1, x1, y2, x2);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class X1, class Y1, class X2, class Y2>
|
template <class X1, class Y1, class X2, class Y2>
|
||||||
void test_subtractable(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
void test_subtractable(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
||||||
{
|
{
|
||||||
sanity_check( x1, y1, x2, y2 );
|
sanity_check(x1, y1, x2, y2);
|
||||||
BOOST_TEST( (x1 - y1).value() == (x2 - y2) );
|
assert((x1 - y1).value() == x2 - y2);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class X1, class Y1, class X2, class Y2>
|
template <class X1, class Y1, class X2, class Y2>
|
||||||
void test_dividable(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
void test_dividable(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
||||||
{
|
{
|
||||||
sanity_check( x1, y1, x2, y2 );
|
sanity_check(x1, y1, x2, y2);
|
||||||
if ( y2 != 0 )
|
if (y2 != 0)
|
||||||
BOOST_TEST( (x1 / y1).value() == (x2 / y2) );
|
assert((x1 / y1).value() == x2 / y2);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class X1, class Y1, class X2, class Y2>
|
template <class X1, class Y1, class X2, class Y2>
|
||||||
void test_modable(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
void test_modable(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
||||||
{
|
{
|
||||||
sanity_check( x1, y1, x2, y2 );
|
sanity_check(x1, y1, x2, y2);
|
||||||
if ( y2 != 0 )
|
if (y2 != 0)
|
||||||
BOOST_TEST( (x1 % y1).value() == (x2 % y2) );
|
assert((x1 / y1).value() == x2 / y2);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class X1, class Y1, class X2, class Y2>
|
template <class X1, class Y1, class X2, class Y2>
|
||||||
void test_xorable_aux(X1 x1, Y1 y1, X2 x2, Y2 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>
|
template <class X1, class Y1, class X2, class Y2>
|
||||||
void test_xorable(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
void test_xorable(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
||||||
{
|
{
|
||||||
sanity_check( x1, y1, x2, y2 );
|
sanity_check(x1, y1, x2, y2);
|
||||||
test_xorable_aux( x1, y1, x2, y2 );
|
test_xorable_aux(x1, y1, x2, y2);
|
||||||
test_xorable_aux( y1, x1, y2, x2 );
|
test_xorable_aux(y1, x1, y2, x2);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class X1, class Y1, class X2, class Y2>
|
template <class X1, class Y1, class X2, class Y2>
|
||||||
void test_andable_aux(X1 x1, Y1 y1, X2 x2, Y2 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>
|
template <class X1, class Y1, class X2, class Y2>
|
||||||
void test_andable(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
void test_andable(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
||||||
{
|
{
|
||||||
sanity_check( x1, y1, x2, y2 );
|
sanity_check(x1, y1, x2, y2);
|
||||||
test_andable_aux( x1, y1, x2, y2 );
|
test_andable_aux(x1, y1, x2, y2);
|
||||||
test_andable_aux( y1, x1, y2, x2 );
|
test_andable_aux(y1, x1, y2, x2);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class X1, class Y1, class X2, class Y2>
|
template <class X1, class Y1, class X2, class Y2>
|
||||||
void test_orable_aux(X1 x1, Y1 y1, X2 x2, Y2 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>
|
template <class X1, class Y1, class X2, class Y2>
|
||||||
void test_orable(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
void test_orable(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
||||||
{
|
{
|
||||||
sanity_check( x1, y1, x2, y2 );
|
sanity_check(x1, y1, x2, y2);
|
||||||
test_orable_aux( x1, y1, x2, y2 );
|
test_orable_aux(x1, y1, x2, y2);
|
||||||
test_orable_aux( y1, x1, y2, x2 );
|
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) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class X1, class X2>
|
template <class X1, class X2>
|
||||||
void test_incrementable(X1 x1, X2 x2)
|
void test_incrementable(X1 x1, X2 x2)
|
||||||
{
|
{
|
||||||
sanity_check( x1, x1, x2, x2 );
|
sanity_check(x1, x1, x2, x2);
|
||||||
BOOST_TEST( (x1++).value() == x2++ );
|
assert(x1++.value() == x2++);
|
||||||
BOOST_TEST( x1.value() == x2 );
|
assert(x1.value() == x2);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class X1, class X2>
|
template <class X1, class X2>
|
||||||
void test_decrementable(X1 x1, X2 x2)
|
void test_decrementable(X1 x1, X2 x2)
|
||||||
{
|
{
|
||||||
sanity_check( x1, x1, x2, x2 );
|
sanity_check(x1, x1, x2, x2);
|
||||||
BOOST_TEST( (x1--).value() == x2-- );
|
assert(x1--.value() == x2--);
|
||||||
BOOST_TEST( x1.value() == x2 );
|
assert(x1.value() == x2);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class X1, class Y1, class X2, class Y2>
|
template <class X1, class Y1, class X2, class Y2>
|
||||||
void test_all(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
void test_all(X1 x1, Y1 y1, X2 x2, Y2 y2)
|
||||||
{
|
{
|
||||||
test_less_than_comparable( x1, y1, x2, y2 );
|
test_less_than_comparable(x1, y1, x2, y2);
|
||||||
test_equality_comparable( x1, y1, x2, y2 );
|
test_equality_comparable(x1, y1, x2, y2);
|
||||||
test_multipliable( x1, y1, x2, y2 );
|
test_multipliable(x1, y1, x2, y2);
|
||||||
test_addable( x1, y1, x2, y2 );
|
test_addable(x1, y1, x2, y2);
|
||||||
test_subtractable( x1, y1, x2, y2 );
|
test_subtractable(x1, y1, x2, y2);
|
||||||
test_dividable( x1, y1, x2, y2 );
|
test_dividable(x1, y1, x2, y2);
|
||||||
test_modable( x1, y1, x2, y2 );
|
test_modable(x1, y1, x2, y2);
|
||||||
test_xorable( x1, y1, x2, y2 );
|
test_xorable(x1, y1, x2, y2);
|
||||||
test_andable( x1, y1, x2, y2 );
|
test_andable(x1, y1, x2, y2);
|
||||||
test_orable( x1, y1, x2, y2 );
|
test_orable(x1, y1, x2, y2);
|
||||||
test_left_shiftable( x1, y1, x2, y2 );
|
test_incrementable(x1, x2);
|
||||||
test_right_shiftable( x1, y1, x2, y2 );
|
test_decrementable(x1, x2);
|
||||||
test_incrementable( x1, x2 );
|
|
||||||
test_decrementable( x1, x2 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Big, class Small>
|
template <class Big, class Small>
|
||||||
struct tester
|
struct tester
|
||||||
{
|
{
|
||||||
void operator()(boost::minstd_rand& randomizer) const
|
void operator()(boost::min_rand& randomizer) const
|
||||||
{
|
{
|
||||||
Big b1 = Big( randomizer() );
|
Big b1 = Big(randomizer());
|
||||||
Big b2 = Big( randomizer() );
|
Big b2 = Big(randomizer());
|
||||||
Small s = Small( randomizer() );
|
Small s = Small(randomizer());
|
||||||
|
|
||||||
test_all( Wrapped1<Big>(b1), Wrapped1<Big>(b2), b1, b2 );
|
test_all(Wrapped1<Big>(b1), Wrapped1<Big>(b2), b1, b2);
|
||||||
test_all( Wrapped2<Big, Small>(b1), s, b1, s );
|
test_all(Wrapped2<Big, Small>(b1), s, b1, s);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// added as a regression test. We had a bug which this uncovered.
|
// added as a regression test. We had a bug which this uncovered.
|
||||||
struct Point
|
struct Point
|
||||||
: boost::addable<Point
|
: boost::addable<Point,
|
||||||
, boost::subtractable<Point> >
|
boost::subtractable<Point> >
|
||||||
{
|
{
|
||||||
Point( int h, int v ) : h(h), v(v) {}
|
Point( int h, int v ) : h(h), v(v) {}
|
||||||
Point() :h(0), v(0) {}
|
Point() :h(0), v(0) {}
|
||||||
const Point& operator+=( const Point& rhs )
|
const Point& operator+=( const Point& rhs ) { h += rhs.h; v += rhs.v; return *this; }
|
||||||
{ 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 h;
|
||||||
int v;
|
int v;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // unnamed namespace
|
} // unnamed namespace
|
||||||
|
|
||||||
|
|
||||||
@@ -429,25 +340,20 @@ template Wrapped2<unsigned long, unsigned char>;
|
|||||||
template Wrapped2<unsigned long, unsigned long>;
|
template Wrapped2<unsigned long, unsigned long>;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define PRIVATE_EXPR_TEST(e, t) BOOST_TEST( ((e), (t)) )
|
#ifdef NDEBUG
|
||||||
|
#error This program is pointless when NDEBUG disables assert()!
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int main()
|
||||||
int
|
|
||||||
test_main( int , char * [] )
|
|
||||||
{
|
{
|
||||||
using std::cout;
|
|
||||||
using std::endl;
|
|
||||||
|
|
||||||
// Regression test.
|
// Regression test.
|
||||||
Point x;
|
Point x;
|
||||||
x = x + Point(3, 4);
|
x = x + Point(3, 4);
|
||||||
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)
|
for (int n = 0; n < 10000; ++n)
|
||||||
{
|
{
|
||||||
boost::minstd_rand r;
|
boost::min_rand r;
|
||||||
tester<long, int>()(r);
|
tester<long, int>()(r);
|
||||||
tester<long, signed char>()(r);
|
tester<long, signed char>()(r);
|
||||||
tester<long, long>()(r);
|
tester<long, long>()(r);
|
||||||
@@ -461,197 +367,115 @@ test_main( int , char * [] )
|
|||||||
tester<unsigned int, unsigned char>()(r);
|
tester<unsigned int, unsigned char>()(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
cout << "Did random tester loop." << endl;
|
|
||||||
|
|
||||||
MyInt i1(1);
|
MyInt i1(1);
|
||||||
MyInt i2(2);
|
MyInt i2(2);
|
||||||
MyInt i;
|
MyInt i;
|
||||||
|
|
||||||
BOOST_TEST( i1.value() == 1 );
|
assert( i1.value() == 1 );
|
||||||
BOOST_TEST( i2.value() == 2 );
|
assert( i2.value() == 2 );
|
||||||
BOOST_TEST( i.value() == 0 );
|
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) );
|
i = i1 + i2; assert( i.value() == 3 );
|
||||||
|
i = i + i2; assert( i.value() == 5 );
|
||||||
BOOST_TEST( i2 == i );
|
i = i - i1; assert( i.value() == 4 );
|
||||||
BOOST_TEST( i1 != i2 );
|
i = i * i2; assert( i.value() == 8 );
|
||||||
BOOST_TEST( i1 < i2 );
|
i = i / i2; assert( i.value() == 4 );
|
||||||
BOOST_TEST( i1 <= i2 );
|
i = i % (i - i1); assert( i.value() == 1 );
|
||||||
BOOST_TEST( i <= i2 );
|
i = i2 + i2; assert( i.value() == 4 );
|
||||||
BOOST_TEST( i2 > i1 );
|
i = i1 | i2 | i; assert( i.value() == 7 );
|
||||||
BOOST_TEST( i2 >= i1 );
|
i = i & i2; assert( i.value() == 2 );
|
||||||
BOOST_TEST( i2 >= i );
|
i = i + i1; assert( i.value() == 3 );
|
||||||
|
i = i ^ i1; assert( i.value() == 2 );
|
||||||
PRIVATE_EXPR_TEST( (i = i1 + i2), (i.value() == 3) );
|
i = (i+i1)*(i2|i1); assert( i.value() == 9 );
|
||||||
PRIVATE_EXPR_TEST( (i = i + i2), (i.value() == 5) );
|
|
||||||
PRIVATE_EXPR_TEST( (i = i - i1), (i.value() == 4) );
|
|
||||||
PRIVATE_EXPR_TEST( (i = i * i2), (i.value() == 8) );
|
|
||||||
PRIVATE_EXPR_TEST( (i = i / i2), (i.value() == 4) );
|
|
||||||
PRIVATE_EXPR_TEST( (i = i % ( i - i1 )), (i.value() == 1) );
|
|
||||||
PRIVATE_EXPR_TEST( (i = i2 + i2), (i.value() == 4) );
|
|
||||||
PRIVATE_EXPR_TEST( (i = i1 | i2 | i), (i.value() == 7) );
|
|
||||||
PRIVATE_EXPR_TEST( (i = i & i2), (i.value() == 2) );
|
|
||||||
PRIVATE_EXPR_TEST( (i = i + i1), (i.value() == 3) );
|
|
||||||
PRIVATE_EXPR_TEST( (i = i ^ i1), (i.value() == 2) );
|
|
||||||
PRIVATE_EXPR_TEST( (i = ( i + i1 ) * ( i2 | i1 )), (i.value() == 9) );
|
|
||||||
|
|
||||||
PRIVATE_EXPR_TEST( (i = i1 << i2), (i.value() == 4) );
|
|
||||||
PRIVATE_EXPR_TEST( (i = i2 >> i1), (i.value() == 1) );
|
|
||||||
|
|
||||||
cout << "Performed tests on MyInt objects.\n";
|
|
||||||
|
|
||||||
MyLong j1(1);
|
MyLong j1(1);
|
||||||
MyLong j2(2);
|
MyLong j2(2);
|
||||||
MyLong j;
|
MyLong j;
|
||||||
|
|
||||||
BOOST_TEST( j1.value() == 1 );
|
assert( j1.value() == 1 );
|
||||||
BOOST_TEST( j2.value() == 2 );
|
assert( j2.value() == 2 );
|
||||||
BOOST_TEST( j.value() == 0 );
|
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 );
|
assert( (j + 2) == 5 );
|
||||||
BOOST_TEST( 2 == j );
|
assert( (3 + j2) == 5 );
|
||||||
BOOST_TEST( j2 == 2 );
|
j = j + j2; assert( j.value() == 5 );
|
||||||
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) );
|
|
||||||
|
|
||||||
BOOST_TEST( (j + 2) == 5 );
|
assert( (j - 1) == 4 );
|
||||||
BOOST_TEST( (3 + j2) == 5 );
|
j = j - j1; assert( j.value() == 4 );
|
||||||
PRIVATE_EXPR_TEST( (j = j + j2), (j.value() == 5) );
|
|
||||||
|
|
||||||
BOOST_TEST( (j - 1) == 4 );
|
assert( (j * 2) == 8 );
|
||||||
PRIVATE_EXPR_TEST( (j = j - j1), (j.value() == 4) );
|
assert( (4 * j2) == 8 );
|
||||||
|
j = j * j2; assert( j.value() == 8 );
|
||||||
|
|
||||||
BOOST_TEST( (j * 2) == 8 );
|
assert( (j / 2) == 4 );
|
||||||
BOOST_TEST( (4 * j2) == 8 );
|
j = j / j2; assert( j.value() == 4 );
|
||||||
PRIVATE_EXPR_TEST( (j = j * j2), (j.value() == 8) );
|
|
||||||
|
|
||||||
BOOST_TEST( (j / 2) == 4 );
|
assert( (j % 3) == 1 );
|
||||||
PRIVATE_EXPR_TEST( (j = j / j2), (j.value() == 4) );
|
j = j % (j - j1); assert( j.value() == 1 );
|
||||||
|
|
||||||
BOOST_TEST( (j % 3) == 1 );
|
j = j2 + j2; assert( j.value() == 4 );
|
||||||
PRIVATE_EXPR_TEST( (j = j % ( j - j1 )), (j.value() == 1) );
|
|
||||||
|
|
||||||
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 );
|
assert( (7 & j2) == 2 );
|
||||||
BOOST_TEST( (j1 | 2 | j) == 7 );
|
assert( (j & 2) == 2 );
|
||||||
BOOST_TEST( (j1 | j2 | 4) == 7 );
|
j = j & j2; assert( j.value() == 2 );
|
||||||
PRIVATE_EXPR_TEST( (j = j1 | j2 | j), (j.value() == 7) );
|
|
||||||
|
|
||||||
BOOST_TEST( (7 & j2) == 2 );
|
j = j | j1; assert( j.value() == 3 );
|
||||||
BOOST_TEST( (j & 2) == 2 );
|
|
||||||
PRIVATE_EXPR_TEST( (j = j & j2), (j.value() == 2) );
|
|
||||||
|
|
||||||
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 );
|
j = (j+j1)*(j2|j1); assert( j.value() == 9 );
|
||||||
BOOST_TEST( (j ^ 1) == 2 );
|
|
||||||
PRIVATE_EXPR_TEST( (j = j ^ j1), (j.value() == 2) );
|
|
||||||
|
|
||||||
PRIVATE_EXPR_TEST( (j = ( j + j1 ) * ( j2 | j1 )), (j.value() == 9) );
|
std::cout << "0 errors detected\n";
|
||||||
|
return 0;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
6
tie.html
6
tie.html
@@ -23,9 +23,7 @@
|
|||||||
<TT>tie</TT>
|
<TT>tie</TT>
|
||||||
</H1>
|
</H1>
|
||||||
|
|
||||||
<h3>
|
<P>
|
||||||
[tie has been deprecated. Its functionality is supplied by the Boost
|
|
||||||
Tuples Library.]</h3>
|
|
||||||
<PRE>
|
<PRE>
|
||||||
template <class A, class B>
|
template <class A, class B>
|
||||||
tied<A,B> tie(A& a, B& b);
|
tied<A,B> tie(A& a, B& b);
|
||||||
@@ -126,7 +124,7 @@ The output is:
|
|||||||
<TABLE>
|
<TABLE>
|
||||||
<TR valign=top>
|
<TR valign=top>
|
||||||
<TD nowrap>Copyright © 2000</TD><TD>
|
<TD nowrap>Copyright © 2000</TD><TD>
|
||||||
<A HREF=file:///c:/boost/site/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
|
Univ.of Notre Dame (<A
|
||||||
HREF="mailto:jsiek@lsc.nd.edu">jsiek@lsc.nd.edu</A>)<br>
|
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>
|
<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>
|
||||||
|
44
utility.htm
44
utility.htm
@@ -16,50 +16,10 @@
|
|||||||
<h2>Contents</h2>
|
<h2>Contents</h2>
|
||||||
|
|
||||||
<ul>
|
<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>Function templates <a href="#functions next">next() and prior()</a></li>
|
||||||
<li>Class <a href="#Class noncopyable">noncopyable</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>
|
<li>Function template <a href="tie.html">tie()</a> and supporting class tied.</li>
|
||||||
</ul>
|
</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>
|
<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
|
<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)
|
concern about the effect on compiler optimization of adding (even trivial inline)
|
||||||
destructor declarations. He says "Probably this concern is misplaced, because
|
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>
|
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>
|
<hr>
|
||||||
<p>Revised <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan
|
<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>
|
||||||
<p><EFBFBD> Copyright boost.org 1999. Permission to copy, use, modify, sell and
|
<p><EFBFBD> Copyright boost.org 1999. Permission to copy, use, modify, sell and
|
||||||
|
Reference in New Issue
Block a user