Compare commits

..

13 Commits

Author SHA1 Message Date
nobody
d9c9685be2 This commit was manufactured by cvs2svn to create branch 'split-config'.
[SVN r10742]
2001-08-04 14:31:38 +00:00
Beman Dawes
31d0908b74 Add workaround for BOOST_NO_STDC_NAMESPACE
[SVN r10681]
2001-07-20 21:29:36 +00:00
Dave Abrahams
32c77599f4 Fixes for ICL
[SVN r10613]
2001-07-14 12:51:59 +00:00
Beman Dawes
812ebf3562 Back out commit made in error
[SVN r10596]
2001-07-12 16:15:30 +00:00
Beman Dawes
37f476013d Change absolute URL's to relative
[SVN r10594]
2001-07-12 15:31:15 +00:00
Dave Abrahams
9f3104166f output_iterator_helper changes: removed default template parameters, added
support for self-proxying, additional documentation and tests (Aleksey Gurtovoy)


[SVN r10576]
2001-07-09 23:51:49 +00:00
Dave Abrahams
64cc0daf34 Integrate Aleksey's changes
[SVN r10575]
2001-07-09 23:50:55 +00:00
Beman Dawes
d5d64df124 Fix broken link
[SVN r10553]
2001-07-06 19:19:45 +00:00
Beman Dawes
0edcfcd5c1 Tuples library causes tie to be deprecated
[SVN r10552]
2001-07-06 19:16:39 +00:00
John Maddock
50ba2d419a Tweeked gcc workaround (gcc 3 still has same problem as gcc 2.9x), added tentative Metrowerks and Intel compiler workarounds.
[SVN r10422]
2001-06-25 11:31:14 +00:00
John Maddock
ff3a77ca5a Fixed problem with VC6 compilers - probably a temporary fix.
[SVN r10361]
2001-06-20 11:43:57 +00:00
Jens Maurer
4eaed6c23d remove superfluous, illegal "typename" (twice)
[SVN r10314]
2001-06-12 18:50:37 +00:00
Jeremy Siek
4d0dd46471 meant to add as a branch
[SVN r10280]
2001-06-06 19:16:34 +00:00
22 changed files with 3851 additions and 2635 deletions

View File

@@ -85,7 +85,7 @@ Once that is done we can drop Multi-Pass Input Iterator.
<TABLE>
<TR valign=top>
<TD nowrap>Copyright &copy 2000</TD><TD>
<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>)
<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>)
</TD></TR></TABLE>
</BODY>

View File

@@ -193,14 +193,14 @@ int main(int argc, char *argv[ ])
int i = 2;
c2(i);
int* pi = &i;
#if defined(BOOST_MSVC6_MEMBER_TEMPLATES) || !defined(BOOST_NO_MEMBER_TEMPLATES)
#if (defined(BOOST_MSVC6_MEMBER_TEMPLATES) || !defined(BOOST_NO_MEMBER_TEMPLATES)) && !defined(__ICL)
call_traits_checker<int*> c3;
c3(pi);
call_traits_checker<int&> c4;
c4(i);
call_traits_checker<const int&> c5;
c5(i);
#if !defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
#if !defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(__MWERKS__)
int a[2] = {1,2};
call_traits_checker<int[2]> c6;
c6(a);
@@ -238,7 +238,7 @@ int main(int argc, char *argv[ ])
type_test(int&, boost::call_traits<int&>::reference)
type_test(const int&, boost::call_traits<int&>::const_reference)
type_test(int&, boost::call_traits<int&>::param_type)
#if !(defined(__GNUC__) && (__GNUC__ < 3))
#if !(defined(__GNUC__) && (__GNUC__ < 4))
type_test(int&, boost::call_traits<cr_type>::value_type)
type_test(int&, boost::call_traits<cr_type>::reference)
type_test(const int&, boost::call_traits<cr_type>::const_reference)

View File

@@ -0,0 +1,23 @@
// (C) Copyright Boost.org 2000. Permission to copy, use, modify, sell and
// distribute this software is granted provided this copyright notice appears
// in all copies. This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// See http://www.boost.org for most recent version including documentation.
// See boost/detail/call_traits.hpp and boost/detail/ob_call_traits.hpp
// for full copyright notices.
#ifndef BOOST_CALL_TRAITS_HPP
#define BOOST_CALL_TRAITS_HPP
#ifndef BOOST_CONFIG_HPP
#include <boost/config.hpp>
#endif
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#include <boost/detail/ob_call_traits.hpp>
#else
#include <boost/detail/call_traits.hpp>
#endif
#endif // BOOST_CALL_TRAITS_HPP

View File

@@ -0,0 +1,23 @@
// (C) Copyright Boost.org 2000. Permission to copy, use, modify, sell and
// distribute this software is granted provided this copyright notice appears
// in all copies. This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// See http://www.boost.org for most recent version including documentation.
// See boost/detail/compressed_pair.hpp and boost/detail/ob_compressed_pair.hpp
// for full copyright notices.
#ifndef BOOST_COMPRESSED_PAIR_HPP
#define BOOST_COMPRESSED_PAIR_HPP
#ifndef BOOST_CONFIG_HPP
#include <boost/config.hpp>
#endif
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
#include <boost/detail/ob_compressed_pair.hpp>
#else
#include <boost/detail/compressed_pair.hpp>
#endif
#endif // BOOST_COMPRESSED_PAIR_HPP

View File

@@ -0,0 +1,141 @@
// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
// Permission to copy, use, modify, sell and
// distribute this software is granted provided this copyright notice appears
// in all copies. This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// See http://www.boost.org for most recent version including documentation.
// call_traits: defines typedefs for function usage
// (see libs/utility/call_traits.htm)
/* Release notes:
23rd July 2000:
Fixed array specialization. (JM)
Added Borland specific fixes for reference types
(issue raised by Steve Cleary).
*/
#ifndef BOOST_DETAIL_CALL_TRAITS_HPP
#define BOOST_DETAIL_CALL_TRAITS_HPP
#ifndef BOOST_CONFIG_HPP
#include <boost/config.hpp>
#endif
#ifndef BOOST_ARITHMETIC_TYPE_TRAITS_HPP
#include <boost/type_traits/arithmetic_traits.hpp>
#endif
#ifndef BOOST_COMPOSITE_TYPE_TRAITS_HPP
#include <boost/type_traits/composite_traits.hpp>
#endif
namespace boost{
namespace detail{
template <typename T, bool isp, bool b1, bool b2>
struct ct_imp
{
typedef const T& param_type;
};
template <typename T, bool isp>
struct ct_imp<T, isp, true, true>
{
typedef T const param_type;
};
template <typename T, bool b1, bool b2>
struct ct_imp<T, true, b1, b2>
{
typedef T const param_type;
};
}
template <typename T>
struct call_traits
{
public:
typedef T value_type;
typedef T& reference;
typedef const T& const_reference;
//
// C++ Builder workaround: we should be able to define a compile time
// constant and pass that as a single template parameter to ct_imp<T,bool>,
// however compiler bugs prevent this - instead pass three bool's to
// ct_imp<T,bool,bool,bool> and add an extra partial specialisation
// of ct_imp to handle the logic. (JM)
typedef typename detail::ct_imp<T, ::boost::is_pointer<typename remove_const<T>::type>::value, ::boost::is_arithmetic<typename remove_const<T>::type>::value, sizeof(T) <= sizeof(void*)>::param_type param_type;
};
template <typename T>
struct call_traits<T&>
{
typedef T& value_type;
typedef T& reference;
typedef const T& const_reference;
typedef T& param_type; // hh removed const
};
#if defined(__BORLANDC__) && (__BORLANDC__ <= 0x551)
// these are illegal specialisations; cv-qualifies applied to
// references have no effect according to [8.3.2p1],
// C++ Builder requires them though as it treats cv-qualified
// references as distinct types...
template <typename T>
struct call_traits<T&const>
{
typedef T& value_type;
typedef T& reference;
typedef const T& const_reference;
typedef T& param_type; // hh removed const
};
template <typename T>
struct call_traits<T&volatile>
{
typedef T& value_type;
typedef T& reference;
typedef const T& const_reference;
typedef T& param_type; // hh removed const
};
template <typename T>
struct call_traits<T&const volatile>
{
typedef T& value_type;
typedef T& reference;
typedef const T& const_reference;
typedef T& param_type; // hh removed const
};
#endif
template <typename T, std::size_t N>
struct call_traits<T [N]>
{
private:
typedef T array_type[N];
public:
// degrades array to pointer:
typedef const T* value_type;
typedef array_type& reference;
typedef const array_type& const_reference;
typedef const T* const param_type;
};
template <typename T, std::size_t N>
struct call_traits<const T [N]>
{
private:
typedef const T array_type[N];
public:
// degrades array to pointer:
typedef const T* value_type;
typedef array_type& reference;
typedef const array_type& const_reference;
typedef const T* const param_type;
};
}
#endif // BOOST_DETAIL_CALL_TRAITS_HPP

View File

@@ -0,0 +1,428 @@
// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
// Permission to copy, use, modify, sell and
// distribute this software is granted provided this copyright notice appears
// in all copies. This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// See http://www.boost.org for most recent version including documentation.
// compressed_pair: pair that "compresses" empty members
// (see libs/utility/compressed_pair.htm)
//
// JM changes 25 Jan 2000:
// Removed default arguments from compressed_pair_switch to get
// C++ Builder 4 to accept them
// rewriten swap to get gcc and C++ builder to compile.
// added partial specialisations for case T1 == T2 to avoid duplicate constructor defs.
#ifndef BOOST_DETAIL_COMPRESSED_PAIR_HPP
#define BOOST_DETAIL_COMPRESSED_PAIR_HPP
#include <algorithm>
#ifndef BOOST_OBJECT_TYPE_TRAITS_HPP
#include <boost/type_traits/object_traits.hpp>
#endif
#ifndef BOOST_SAME_TRAITS_HPP
#include <boost/type_traits/same_traits.hpp>
#endif
#ifndef BOOST_CALL_TRAITS_HPP
#include <boost/call_traits.hpp>
#endif
namespace boost
{
// compressed_pair
namespace details
{
// JM altered 26 Jan 2000:
template <class T1, class T2, bool IsSame, bool FirstEmpty, bool SecondEmpty>
struct compressed_pair_switch;
template <class T1, class T2>
struct compressed_pair_switch<T1, T2, false, false, false>
{static const int value = 0;};
template <class T1, class T2>
struct compressed_pair_switch<T1, T2, false, true, true>
{static const int value = 3;};
template <class T1, class T2>
struct compressed_pair_switch<T1, T2, false, true, false>
{static const int value = 1;};
template <class T1, class T2>
struct compressed_pair_switch<T1, T2, false, false, true>
{static const int value = 2;};
template <class T1, class T2>
struct compressed_pair_switch<T1, T2, true, true, true>
{static const int value = 4;};
template <class T1, class T2>
struct compressed_pair_switch<T1, T2, true, false, false>
{static const int value = 5;};
template <class T1, class T2, int Version> class compressed_pair_imp;
#ifdef __GNUC__
// workaround for GCC (JM):
using std::swap;
#endif
//
// can't call unqualified swap from within classname::swap
// as Koenig lookup rules will find only the classname::swap
// member function not the global declaration, so use cp_swap
// as a forwarding function (JM):
template <typename T>
inline void cp_swap(T& t1, T& t2)
{
#ifndef __GNUC__
using std::swap;
#endif
swap(t1, t2);
}
// 0 derive from neither
template <class T1, class T2>
class compressed_pair_imp<T1, T2, 0>
{
public:
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;
typedef typename call_traits<first_type>::reference first_reference;
typedef typename call_traits<second_type>::reference second_reference;
typedef typename call_traits<first_type>::const_reference first_const_reference;
typedef typename call_traits<second_type>::const_reference second_const_reference;
compressed_pair_imp() {}
compressed_pair_imp(first_param_type x, second_param_type y)
: first_(x), second_(y) {}
explicit compressed_pair_imp(first_param_type x)
: first_(x) {}
explicit compressed_pair_imp(second_param_type y)
: second_(y) {}
first_reference first() {return first_;}
first_const_reference first() const {return first_;}
second_reference second() {return second_;}
second_const_reference second() const {return second_;}
void swap(compressed_pair_imp& y)
{
cp_swap(first_, y.first_);
cp_swap(second_, y.second_);
}
private:
first_type first_;
second_type second_;
};
// 1 derive from T1
template <class T1, class T2>
class compressed_pair_imp<T1, T2, 1>
: private T1
{
public:
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;
typedef typename call_traits<first_type>::reference first_reference;
typedef typename call_traits<second_type>::reference second_reference;
typedef typename call_traits<first_type>::const_reference first_const_reference;
typedef typename call_traits<second_type>::const_reference second_const_reference;
compressed_pair_imp() {}
compressed_pair_imp(first_param_type x, second_param_type y)
: first_type(x), second_(y) {}
explicit compressed_pair_imp(first_param_type x)
: first_type(x) {}
explicit compressed_pair_imp(second_param_type y)
: second_(y) {}
first_reference first() {return *this;}
first_const_reference first() const {return *this;}
second_reference second() {return second_;}
second_const_reference second() const {return second_;}
void swap(compressed_pair_imp& y)
{
// no need to swap empty base class:
cp_swap(second_, y.second_);
}
private:
second_type second_;
};
// 2 derive from T2
template <class T1, class T2>
class compressed_pair_imp<T1, T2, 2>
: private T2
{
public:
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;
typedef typename call_traits<first_type>::reference first_reference;
typedef typename call_traits<second_type>::reference second_reference;
typedef typename call_traits<first_type>::const_reference first_const_reference;
typedef typename call_traits<second_type>::const_reference second_const_reference;
compressed_pair_imp() {}
compressed_pair_imp(first_param_type x, second_param_type y)
: second_type(y), first_(x) {}
explicit compressed_pair_imp(first_param_type x)
: first_(x) {}
explicit compressed_pair_imp(second_param_type y)
: second_type(y) {}
first_reference first() {return first_;}
first_const_reference first() const {return first_;}
second_reference second() {return *this;}
second_const_reference second() const {return *this;}
void swap(compressed_pair_imp& y)
{
// no need to swap empty base class:
cp_swap(first_, y.first_);
}
private:
first_type first_;
};
// 3 derive from T1 and T2
template <class T1, class T2>
class compressed_pair_imp<T1, T2, 3>
: private T1,
private T2
{
public:
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;
typedef typename call_traits<first_type>::reference first_reference;
typedef typename call_traits<second_type>::reference second_reference;
typedef typename call_traits<first_type>::const_reference first_const_reference;
typedef typename call_traits<second_type>::const_reference second_const_reference;
compressed_pair_imp() {}
compressed_pair_imp(first_param_type x, second_param_type y)
: first_type(x), second_type(y) {}
explicit compressed_pair_imp(first_param_type x)
: first_type(x) {}
explicit compressed_pair_imp(second_param_type y)
: second_type(y) {}
first_reference first() {return *this;}
first_const_reference first() const {return *this;}
second_reference second() {return *this;}
second_const_reference second() const {return *this;}
//
// no need to swap empty bases:
void swap(compressed_pair_imp&) {}
};
// JM
// 4 T1 == T2, T1 and T2 both empty
// Note does not actually store an instance of T2 at all -
// but reuses T1 base class for both first() and second().
template <class T1, class T2>
class compressed_pair_imp<T1, T2, 4>
: private T1
{
public:
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;
typedef typename call_traits<first_type>::reference first_reference;
typedef typename call_traits<second_type>::reference second_reference;
typedef typename call_traits<first_type>::const_reference first_const_reference;
typedef typename call_traits<second_type>::const_reference second_const_reference;
compressed_pair_imp() {}
compressed_pair_imp(first_param_type x, second_param_type)
: first_type(x) {}
explicit compressed_pair_imp(first_param_type x)
: first_type(x) {}
first_reference first() {return *this;}
first_const_reference first() const {return *this;}
second_reference second() {return *this;}
second_const_reference second() const {return *this;}
void swap(compressed_pair_imp&) {}
private:
};
// 5 T1 == T2 and are not empty: //JM
template <class T1, class T2>
class compressed_pair_imp<T1, T2, 5>
{
public:
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;
typedef typename call_traits<first_type>::reference first_reference;
typedef typename call_traits<second_type>::reference second_reference;
typedef typename call_traits<first_type>::const_reference first_const_reference;
typedef typename call_traits<second_type>::const_reference second_const_reference;
compressed_pair_imp() {}
compressed_pair_imp(first_param_type x, second_param_type y)
: first_(x), second_(y) {}
explicit compressed_pair_imp(first_param_type x)
: first_(x), second_(x) {}
first_reference first() {return first_;}
first_const_reference first() const {return first_;}
second_reference second() {return second_;}
second_const_reference second() const {return second_;}
void swap(compressed_pair_imp<T1, T2, 5>& y)
{
cp_swap(first_, y.first_);
cp_swap(second_, y.second_);
}
private:
first_type first_;
second_type second_;
};
} // details
template <class T1, class T2>
class compressed_pair
: private ::boost::details::compressed_pair_imp<T1, T2,
::boost::details::compressed_pair_switch<
T1,
T2,
::boost::is_same<typename remove_cv<T1>::type, typename remove_cv<T2>::type>::value,
::boost::is_empty<T1>::value,
::boost::is_empty<T2>::value>::value>
{
private:
typedef details::compressed_pair_imp<T1, T2,
::boost::details::compressed_pair_switch<
T1,
T2,
::boost::is_same<typename remove_cv<T1>::type, typename remove_cv<T2>::type>::value,
::boost::is_empty<T1>::value,
::boost::is_empty<T2>::value>::value> base;
public:
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;
typedef typename call_traits<first_type>::reference first_reference;
typedef typename call_traits<second_type>::reference second_reference;
typedef typename call_traits<first_type>::const_reference first_const_reference;
typedef typename call_traits<second_type>::const_reference second_const_reference;
compressed_pair() : base() {}
compressed_pair(first_param_type x, second_param_type y) : base(x, y) {}
explicit compressed_pair(first_param_type x) : base(x) {}
explicit compressed_pair(second_param_type y) : base(y) {}
first_reference first() {return base::first();}
first_const_reference first() const {return base::first();}
second_reference second() {return base::second();}
second_const_reference second() const {return base::second();}
void swap(compressed_pair& y) { base::swap(y); }
};
// JM
// Partial specialisation for case where T1 == T2:
//
template <class T>
class compressed_pair<T, T>
: private details::compressed_pair_imp<T, T,
::boost::details::compressed_pair_switch<
T,
T,
::boost::is_same<typename remove_cv<T>::type, typename remove_cv<T>::type>::value,
::boost::is_empty<T>::value,
::boost::is_empty<T>::value>::value>
{
private:
typedef details::compressed_pair_imp<T, T,
::boost::details::compressed_pair_switch<
T,
T,
::boost::is_same<typename remove_cv<T>::type, typename remove_cv<T>::type>::value,
::boost::is_empty<T>::value,
::boost::is_empty<T>::value>::value> base;
public:
typedef T first_type;
typedef T second_type;
typedef typename call_traits<first_type>::param_type first_param_type;
typedef typename call_traits<second_type>::param_type second_param_type;
typedef typename call_traits<first_type>::reference first_reference;
typedef typename call_traits<second_type>::reference second_reference;
typedef typename call_traits<first_type>::const_reference first_const_reference;
typedef typename call_traits<second_type>::const_reference second_const_reference;
compressed_pair() : base() {}
compressed_pair(first_param_type x, second_param_type y) : base(x, y) {}
explicit compressed_pair(first_param_type x) : base(x) {}
first_reference first() {return base::first();}
first_const_reference first() const {return base::first();}
second_reference second() {return base::second();}
second_const_reference second() const {return base::second();}
void swap(compressed_pair& y) { base::swap(y); }
};
template <class T1, class T2>
inline
void
swap(compressed_pair<T1, T2>& x, compressed_pair<T1, T2>& y)
{
x.swap(y);
}
} // boost
#endif // BOOST_DETAIL_COMPRESSED_PAIR_HPP

View File

@@ -0,0 +1,128 @@
// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
// Permission to copy, use, modify, sell and
// distribute this software is granted provided this copyright notice appears
// in all copies. This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// See http://www.boost.org for most recent version including documentation.
//
// Crippled version for crippled compilers:
// see libs/utility/call_traits.htm
//
/* Release notes:
01st October 2000:
Fixed call_traits on VC6, using "poor man's partial specialisation",
using ideas taken from "Generative programming" by Krzysztof Czarnecki
& Ulrich Eisenecker.
*/
#ifndef BOOST_OB_CALL_TRAITS_HPP
#define BOOST_OB_CALL_TRAITS_HPP
#ifndef BOOST_CONFIG_HPP
#include <boost/config.hpp>
#endif
#ifndef BOOST_ARITHMETIC_TYPE_TRAITS_HPP
#include <boost/type_traits/arithmetic_traits.hpp>
#endif
#ifndef BOOST_COMPOSITE_TYPE_TRAITS_HPP
#include <boost/type_traits/composite_traits.hpp>
#endif
namespace boost{
#if defined(BOOST_MSVC6_MEMBER_TEMPLATES) || !defined(BOOST_NO_MEMBER_TEMPLATES)
//
// use member templates to emulate
// partial specialisation:
//
namespace detail{
template <class T>
struct standard_call_traits
{
typedef T value_type;
typedef T& reference;
typedef const T& const_reference;
typedef const T& param_type;
};
template <class T>
struct simple_call_traits
{
typedef T value_type;
typedef T& reference;
typedef const T& const_reference;
typedef const T param_type;
};
template <class T>
struct reference_call_traits
{
typedef T value_type;
typedef T reference;
typedef T const_reference;
typedef T param_type;
};
template <bool simple, bool reference>
struct call_traits_chooser
{
template <class T>
struct rebind
{
typedef standard_call_traits<T> type;
};
};
template <>
struct call_traits_chooser<true, false>
{
template <class T>
struct rebind
{
typedef simple_call_traits<T> type;
};
};
template <>
struct call_traits_chooser<false, true>
{
template <class T>
struct rebind
{
typedef reference_call_traits<T> type;
};
};
} // namespace detail
template <typename T>
struct call_traits
{
private:
typedef detail::call_traits_chooser<(is_pointer<T>::value || is_arithmetic<T>::value) && sizeof(T) <= sizeof(void*), is_reference<T>::value> chooser;
typedef typename chooser::template rebind<T> bound_type;
typedef typename bound_type::type call_traits_type;
public:
typedef typename call_traits_type::value_type value_type;
typedef typename call_traits_type::reference reference;
typedef typename call_traits_type::const_reference const_reference;
typedef typename call_traits_type::param_type param_type;
};
#else
//
// sorry call_traits is completely non-functional
// blame your broken compiler:
//
template <typename T>
struct call_traits
{
typedef T value_type;
typedef T& reference;
typedef const T& const_reference;
typedef const T& param_type;
};
#endif // member templates
}
#endif // BOOST_OB_CALL_TRAITS_HPP

View File

@@ -0,0 +1,509 @@
// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000.
// Permission to copy, use, modify, sell and
// distribute this software is granted provided this copyright notice appears
// in all copies. This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
// See http://www.boost.org for most recent version including documentation.
// see libs/utility/compressed_pair.hpp
//
/* Release notes:
20 Jan 2001:
Fixed obvious bugs (David Abrahams)
07 Oct 2000:
Added better single argument constructor support.
03 Oct 2000:
Added VC6 support (JM).
23rd July 2000:
Additional comments added. (JM)
Jan 2000:
Original version: this version crippled for use with crippled compilers
- John Maddock Jan 2000.
*/
#ifndef BOOST_OB_COMPRESSED_PAIR_HPP
#define BOOST_OB_COMPRESSED_PAIR_HPP
#include <algorithm>
#ifndef BOOST_OBJECT_TYPE_TRAITS_HPP
#include <boost/type_traits/object_traits.hpp>
#endif
#ifndef BOOST_SAME_TRAITS_HPP
#include <boost/type_traits/same_traits.hpp>
#endif
#ifndef BOOST_CALL_TRAITS_HPP
#include <boost/call_traits.hpp>
#endif
namespace boost
{
#if defined(BOOST_MSVC6_MEMBER_TEMPLATES) || !defined(BOOST_NO_MEMBER_TEMPLATES)
//
// use member templates to emulate
// partial specialisation. Note that due to
// problems with overload resolution with VC6
// each of the compressed_pair versions that follow
// have one template single-argument constructor
// in place of two specific constructors:
//
template <class T1, class T2>
class compressed_pair;
namespace detail{
template <class A, class T1, class T2>
struct best_conversion_traits
{
typedef char one;
typedef char (&two)[2];
static A a;
static one test(T1);
static two test(T2);
enum { value = sizeof(test(a)) };
};
template <int>
struct init_one;
template <>
struct init_one<1>
{
template <class A, class T1, class T2>
static void init(const A& a, T1* p1, T2*)
{
*p1 = a;
}
};
template <>
struct init_one<2>
{
template <class A, class T1, class T2>
static void init(const A& a, T1*, T2* p2)
{
*p2 = a;
}
};
// T1 != T2, both non-empty
template <class T1, class T2>
class compressed_pair_0
{
private:
T1 _first;
T2 _second;
public:
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;
typedef typename call_traits<first_type>::reference first_reference;
typedef typename call_traits<second_type>::reference second_reference;
typedef typename call_traits<first_type>::const_reference first_const_reference;
typedef typename call_traits<second_type>::const_reference second_const_reference;
compressed_pair_0() : _first(), _second() {}
compressed_pair_0(first_param_type x, second_param_type y) : _first(x), _second(y) {}
template <class A>
explicit compressed_pair_0(const A& val)
{
init_one<best_conversion_traits<A, T1, T2>::value>::init(val, &_first, &_second);
}
compressed_pair_0(const ::boost::compressed_pair<T1,T2>& x)
: _first(x.first()), _second(x.second()) {}
#if 0
compressed_pair_0& operator=(const compressed_pair_0& x) {
cout << "assigning compressed pair 0" << endl;
_first = x._first;
_second = x._second;
cout << "finished assigning compressed pair 0" << endl;
return *this;
}
#endif
first_reference first() { return _first; }
first_const_reference first() const { return _first; }
second_reference second() { return _second; }
second_const_reference second() const { return _second; }
void swap(compressed_pair_0& y)
{
using std::swap;
swap(_first, y._first);
swap(_second, y._second);
}
};
// T1 != T2, T2 empty
template <class T1, class T2>
class compressed_pair_1 : T2
{
private:
T1 _first;
public:
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;
typedef typename call_traits<first_type>::reference first_reference;
typedef typename call_traits<second_type>::reference second_reference;
typedef typename call_traits<first_type>::const_reference first_const_reference;
typedef typename call_traits<second_type>::const_reference second_const_reference;
compressed_pair_1() : T2(), _first() {}
compressed_pair_1(first_param_type x, second_param_type y) : T2(y), _first(x) {}
template <class A>
explicit compressed_pair_1(const A& val)
{
init_one<best_conversion_traits<A, T1, T2>::value>::init(val, &_first, static_cast<T2*>(this));
}
compressed_pair_1(const ::boost::compressed_pair<T1,T2>& x)
: T2(x.second()), _first(x.first()) {}
#ifdef BOOST_MSVC
// Total weirdness. If the assignment to _first is moved after
// the call to the inherited operator=, then this breaks graph/test/graph.cpp
// by way of iterator_adaptor.
compressed_pair_1& operator=(const compressed_pair_1& x) {
_first = x._first;
T2::operator=(x);
return *this;
}
#endif
first_reference first() { return _first; }
first_const_reference first() const { return _first; }
second_reference second() { return *this; }
second_const_reference second() const { return *this; }
void swap(compressed_pair_1& y)
{
// no need to swap empty base class:
using std::swap;
swap(_first, y._first);
}
};
// T1 != T2, T1 empty
template <class T1, class T2>
class compressed_pair_2 : T1
{
private:
T2 _second;
public:
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;
typedef typename call_traits<first_type>::reference first_reference;
typedef typename call_traits<second_type>::reference second_reference;
typedef typename call_traits<first_type>::const_reference first_const_reference;
typedef typename call_traits<second_type>::const_reference second_const_reference;
compressed_pair_2() : T1(), _second() {}
compressed_pair_2(first_param_type x, second_param_type y) : T1(x), _second(y) {}
template <class A>
explicit compressed_pair_2(const A& val)
{
init_one<best_conversion_traits<A, T1, T2>::value>::init(val, static_cast<T1*>(this), &_second);
}
compressed_pair_2(const ::boost::compressed_pair<T1,T2>& x)
: T1(x.first()), _second(x.second()) {}
#if 0
compressed_pair_2& operator=(const compressed_pair_2& x) {
cout << "assigning compressed pair 2" << endl;
T1::operator=(x);
_second = x._second;
cout << "finished assigning compressed pair 2" << endl;
return *this;
}
#endif
first_reference first() { return *this; }
first_const_reference first() const { return *this; }
second_reference second() { return _second; }
second_const_reference second() const { return _second; }
void swap(compressed_pair_2& y)
{
// no need to swap empty base class:
using std::swap;
swap(_second, y._second);
}
};
// T1 != T2, both empty
template <class T1, class T2>
class compressed_pair_3 : T1, T2
{
public:
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;
typedef typename call_traits<first_type>::reference first_reference;
typedef typename call_traits<second_type>::reference second_reference;
typedef typename call_traits<first_type>::const_reference first_const_reference;
typedef typename call_traits<second_type>::const_reference second_const_reference;
compressed_pair_3() : T1(), T2() {}
compressed_pair_3(first_param_type x, second_param_type y) : T1(x), T2(y) {}
template <class A>
explicit compressed_pair_3(const A& val)
{
init_one<best_conversion_traits<A, T1, T2>::value>::init(val, static_cast<T1*>(this), static_cast<T2*>(this));
}
compressed_pair_3(const ::boost::compressed_pair<T1,T2>& x)
: T1(x.first()), T2(x.second()) {}
first_reference first() { return *this; }
first_const_reference first() const { return *this; }
second_reference second() { return *this; }
second_const_reference second() const { return *this; }
void swap(compressed_pair_3& y)
{
// no need to swap empty base classes:
}
};
// T1 == T2, and empty
template <class T1, class T2>
class compressed_pair_4 : T1
{
public:
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;
typedef typename call_traits<first_type>::reference first_reference;
typedef typename call_traits<second_type>::reference second_reference;
typedef typename call_traits<first_type>::const_reference first_const_reference;
typedef typename call_traits<second_type>::const_reference second_const_reference;
compressed_pair_4() : T1() {}
compressed_pair_4(first_param_type x, second_param_type) : T1(x) {}
// only one single argument constructor since T1 == T2
explicit compressed_pair_4(first_param_type x) : T1(x) {}
compressed_pair_4(const ::boost::compressed_pair<T1,T2>& x)
: T1(x.first()){}
first_reference first() { return *this; }
first_const_reference first() const { return *this; }
second_reference second() { return *this; }
second_const_reference second() const { return *this; }
void swap(compressed_pair_4& y)
{
// no need to swap empty base classes:
}
};
// T1 == T2, not empty
template <class T1, class T2>
class compressed_pair_5
{
private:
T1 _first;
T2 _second;
public:
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;
typedef typename call_traits<first_type>::reference first_reference;
typedef typename call_traits<second_type>::reference second_reference;
typedef typename call_traits<first_type>::const_reference first_const_reference;
typedef typename call_traits<second_type>::const_reference second_const_reference;
compressed_pair_5() : _first(), _second() {}
compressed_pair_5(first_param_type x, second_param_type y) : _first(x), _second(y) {}
// only one single argument constructor since T1 == T2
explicit compressed_pair_5(first_param_type x) : _first(x), _second(x) {}
compressed_pair_5(const ::boost::compressed_pair<T1,T2>& c)
: _first(c.first()), _second(c.second()) {}
first_reference first() { return _first; }
first_const_reference first() const { return _first; }
second_reference second() { return _second; }
second_const_reference second() const { return _second; }
void swap(compressed_pair_5& y)
{
using std::swap;
swap(_first, y._first);
swap(_second, y._second);
}
};
template <bool e1, bool e2, bool same>
struct compressed_pair_chooser
{
template <class T1, class T2>
struct rebind
{
typedef compressed_pair_0<T1, T2> type;
};
};
template <>
struct compressed_pair_chooser<false, true, false>
{
template <class T1, class T2>
struct rebind
{
typedef compressed_pair_1<T1, T2> type;
};
};
template <>
struct compressed_pair_chooser<true, false, false>
{
template <class T1, class T2>
struct rebind
{
typedef compressed_pair_2<T1, T2> type;
};
};
template <>
struct compressed_pair_chooser<true, true, false>
{
template <class T1, class T2>
struct rebind
{
typedef compressed_pair_3<T1, T2> type;
};
};
template <>
struct compressed_pair_chooser<true, true, true>
{
template <class T1, class T2>
struct rebind
{
typedef compressed_pair_4<T1, T2> type;
};
};
template <>
struct compressed_pair_chooser<false, false, true>
{
template <class T1, class T2>
struct rebind
{
typedef compressed_pair_5<T1, T2> type;
};
};
template <class T1, class T2>
struct compressed_pair_traits
{
private:
typedef compressed_pair_chooser<is_empty<T1>::value, is_empty<T2>::value, is_same<T1,T2>::value> chooser;
typedef typename chooser::template rebind<T1, T2> bound_type;
public:
typedef typename bound_type::type type;
};
} // namespace detail
template <class T1, class T2>
class compressed_pair : public detail::compressed_pair_traits<T1, T2>::type
{
private:
typedef typename detail::compressed_pair_traits<T1, T2>::type base_type;
public:
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;
typedef typename call_traits<first_type>::reference first_reference;
typedef typename call_traits<second_type>::reference second_reference;
typedef typename call_traits<first_type>::const_reference first_const_reference;
typedef typename call_traits<second_type>::const_reference second_const_reference;
compressed_pair() : base_type() {}
compressed_pair(first_param_type x, second_param_type y) : base_type(x, y) {}
template <class A>
explicit compressed_pair(const A& x) : base_type(x){}
first_reference first() { return base_type::first(); }
first_const_reference first() const { return base_type::first(); }
second_reference second() { return base_type::second(); }
second_const_reference second() const { return base_type::second(); }
};
template <class T1, class T2>
inline void swap(compressed_pair<T1, T2>& x, compressed_pair<T1, T2>& y)
{
x.swap(y);
}
#else
// no partial specialisation, no member templates:
template <class T1, class T2>
class compressed_pair
{
private:
T1 _first;
T2 _second;
public:
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;
typedef typename call_traits<first_type>::reference first_reference;
typedef typename call_traits<second_type>::reference second_reference;
typedef typename call_traits<first_type>::const_reference first_const_reference;
typedef typename call_traits<second_type>::const_reference second_const_reference;
compressed_pair() : _first(), _second() {}
compressed_pair(first_param_type x, second_param_type y) : _first(x), _second(y) {}
explicit compressed_pair(first_param_type x) : _first(x), _second() {}
// can't define this in case T1 == T2:
// explicit compressed_pair(second_param_type y) : _first(), _second(y) {}
first_reference first() { return _first; }
first_const_reference first() const { return _first; }
second_reference second() { return _second; }
second_const_reference second() const { return _second; }
void swap(compressed_pair& y)
{
using std::swap;
swap(_first, y._first);
swap(_second, y._second);
}
};
template <class T1, class T2>
inline void swap(compressed_pair<T1, T2>& x, compressed_pair<T1, T2>& y)
{
x.swap(y);
}
#endif
} // boost
#endif // BOOST_OB_COMPRESSED_PAIR_HPP

767
include/boost/operators.hpp Normal file
View File

@@ -0,0 +1,767 @@
// Boost operators.hpp header file ----------------------------------------//
// (C) Copyright David Abrahams, Jeremy Siek, and Daryle Walker 1999-2001.
// Permission to copy, use, modify, sell and distribute this software is
// granted provided this copyright notice appears in all copies. This
// software is provided "as is" without express or implied warranty, and
// with no claim as to its suitability for any purpose.
// See http://www.boost.org for most recent version including documentation.
// Revision History
// 25 Jun 01 output_iterator_helper changes: removed default template
// parameters, added support for self-proxying, additional
// documentation and tests (Aleksey Gurtovoy)
// 29 May 01 Added operator classes for << and >>. Added input and output
// iterator helper classes. Added classes to connect equality and
// relational operators. Added classes for groups of related
// operators. Reimplemented example operator and iterator helper
// classes in terms of the new groups. (Daryle Walker, with help
// from Alexy Gurtovoy)
// 11 Feb 01 Fixed bugs in the iterator helpers which prevented explicitly
// supplied arguments from actually being used (Dave Abrahams)
// 04 Jul 00 Fixed NO_OPERATORS_IN_NAMESPACE bugs, major cleanup and
// refactoring of compiler workarounds, additional documentation
// (Alexy Gurtovoy and Mark Rodgers with some help and prompting from
// Dave Abrahams)
// 28 Jun 00 General cleanup and integration of bugfixes from Mark Rodgers and
// Jeremy Siek (Dave Abrahams)
// 20 Jun 00 Changes to accommodate Borland C++Builder 4 and Borland C++ 5.5
// (Mark Rodgers)
// 20 Jun 00 Minor fixes to the prior revision (Aleksey Gurtovoy)
// 10 Jun 00 Support for the base class chaining technique was added
// (Aleksey Gurtovoy). See documentation and the comments below
// for the details.
// 12 Dec 99 Initial version with iterator operators (Jeremy Siek)
// 18 Nov 99 Change name "divideable" to "dividable", remove unnecessary
// specializations of dividable, subtractable, modable (Ed Brey)
// 17 Nov 99 Add comments (Beman Dawes)
// Remove unnecessary specialization of operators<> (Ed Brey)
// 15 Nov 99 Fix less_than_comparable<T,U> second operand type for first two
// operators.(Beman Dawes)
// 12 Nov 99 Add operators templates (Ed Brey)
// 11 Nov 99 Add single template parameter version for compilers without
// partial specialization (Beman Dawes)
// 10 Nov 99 Initial version
// 10 Jun 00:
// An additional optional template parameter was added to most of
// operator templates to support the base class chaining technique (see
// documentation for the details). Unfortunately, a straightforward
// implementation of this change would have broken compatibility with the
// previous version of the library by making it impossible to use the same
// template name (e.g. 'addable') for both the 1- and 2-argument versions of
// an operator template. This implementation solves the backward-compatibility
// issue at the cost of some simplicity.
//
// One of the complications is an existence of special auxiliary class template
// 'is_chained_base<>' (see 'detail' namespace below), which is used
// to determine whether its template parameter is a library's operator template
// or not. You have to specialize 'is_chained_base<>' for each new
// operator template you add to the library.
//
// However, most of the non-trivial implementation details are hidden behind
// several local macros defined below, and as soon as you understand them,
// you understand the whole library implementation.
#ifndef BOOST_OPERATORS_HPP
#define BOOST_OPERATORS_HPP
#include <boost/config.hpp>
#include <boost/iterator.hpp>
#if defined(__sgi) && !defined(__GNUC__)
#pragma set woff 1234
#endif
#if defined(BOOST_MSVC)
# pragma warning( disable : 4284 ) // complaint about return type of
#endif // operator-> not begin a UDT
namespace boost {
namespace detail {
class empty_base {};
} // namespace detail
} // namespace boost
// In this section we supply the xxxx1 and xxxx2 forms of the operator
// templates, which are explicitly targeted at the 1-type-argument and
// 2-type-argument operator forms, respectively. Some compilers get confused
// when inline friend functions are overloaded in namespaces other than the
// global namespace. When BOOST_NO_OPERATORS_IN_NAMESPACE is defined, all of
// these templates must go in the global namespace.
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
namespace boost
{
#endif
// Basic operator classes (contributed by Dave Abrahams) ------------------//
// Note that friend functions defined in a class are implicitly inline.
// See the C++ std, 11.4 [class.friend] paragraph 5
template <class T, class U, class B = ::boost::detail::empty_base>
struct less_than_comparable2 : B
{
friend bool operator<=(const T& x, const U& y) { return !(x > y); }
friend bool operator>=(const T& x, const U& y) { return !(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); }
friend bool operator>=(const U& x, const T& y) { return !(y > x); }
};
template <class T, class B = ::boost::detail::empty_base>
struct less_than_comparable1 : B
{
friend bool operator>(const T& x, const T& y) { return y < x; }
friend bool operator<=(const T& x, const T& y) { return !(y < x); }
friend bool operator>=(const T& x, const T& y) { return !(x < y); }
};
template <class T, class U, class B = ::boost::detail::empty_base>
struct equality_comparable2 : B
{
friend bool operator==(const U& y, const T& x) { return x == y; }
friend bool operator!=(const U& y, const T& x) { return !(x == y); }
friend bool operator!=(const T& y, const U& x) { return !(y == x); }
};
template <class T, class B = ::boost::detail::empty_base>
struct equality_comparable1 : B
{
friend bool operator!=(const T& x, const T& y) { return !(x == y); }
};
template <class T, class U, class B = ::boost::detail::empty_base>
struct multipliable2 : B
{
friend T operator*(T x, const U& y) { return x *= y; }
friend T operator*(const U& y, T x) { return x *= y; }
};
template <class T, class B = ::boost::detail::empty_base>
struct multipliable1 : B
{
friend T operator*(T x, const T& y) { return x *= y; }
};
template <class T, class U, class B = ::boost::detail::empty_base>
struct addable2 : B
{
friend T operator+(T x, const U& y) { return x += y; }
friend T operator+(const U& y, T x) { return x += y; }
};
template <class T, class B = ::boost::detail::empty_base>
struct addable1 : B
{
friend T operator+(T x, const T& y) { return x += y; }
};
template <class T, class U, class B = ::boost::detail::empty_base>
struct subtractable2 : B
{
friend T operator-(T x, const U& y) { return x -= y; }
};
template <class T, class B = ::boost::detail::empty_base>
struct subtractable1 : B
{
friend T operator-(T x, const T& y) { return x -= y; }
};
template <class T, class U, class B = ::boost::detail::empty_base>
struct dividable2 : B
{
friend T operator/(T x, const U& y) { return x /= y; }
};
template <class T, class B = ::boost::detail::empty_base>
struct dividable1 : B
{
friend T operator/(T x, const T& y) { return x /= y; }
};
template <class T, class U, class B = ::boost::detail::empty_base>
struct modable2 : B
{
friend T operator%(T x, const U& y) { return x %= y; }
};
template <class T, class B = ::boost::detail::empty_base>
struct modable1 : B
{
friend T operator%(T x, const T& y) { return x %= y; }
};
template <class T, class U, class B = ::boost::detail::empty_base>
struct xorable2 : B
{
friend T operator^(T x, const U& y) { return x ^= y; }
friend T operator^(const U& y, T x) { return x ^= y; }
};
template <class T, class B = ::boost::detail::empty_base>
struct xorable1 : B
{
friend T operator^(T x, const T& y) { return x ^= y; }
};
template <class T, class U, class B = ::boost::detail::empty_base>
struct andable2 : B
{
friend T operator&(T x, const U& y) { return x &= y; }
friend T operator&(const U& y, T x) { return x &= y; }
};
template <class T, class B = ::boost::detail::empty_base>
struct andable1 : B
{
friend T operator&(T x, const T& y) { return x &= y; }
};
template <class T, class U, class B = ::boost::detail::empty_base>
struct orable2 : B
{
friend T operator|(T x, const U& y) { return x |= y; }
friend T operator|(const U& y, T x) { return x |= y; }
};
template <class T, class B = ::boost::detail::empty_base>
struct orable1 : B
{
friend T operator|(T x, const T& y) { return x |= y; }
};
// incrementable and decrementable contributed by Jeremy Siek
template <class T, class B = ::boost::detail::empty_base>
struct incrementable : B
{
friend T operator++(T& x, int)
{
incrementable_type tmp(x);
++x;
return tmp;
}
private: // The use of this typedef works around a Borland bug
typedef T incrementable_type;
};
template <class T, class B = ::boost::detail::empty_base>
struct decrementable : B
{
friend T operator--(T& x, int)
{
decrementable_type tmp(x);
--x;
return tmp;
}
private: // The use of this typedef works around a Borland bug
typedef T decrementable_type;
};
// Iterator operator classes (contributed by Jeremy Siek) ------------------//
template <class T, class P, class B = ::boost::detail::empty_base>
struct dereferenceable : B
{
P operator->() const
{
return &*static_cast<const T&>(*this);
}
};
template <class T, class I, class R, class B = ::boost::detail::empty_base>
struct indexable : B
{
R operator[](I n) const
{
return *(static_cast<const T&>(*this) + n);
}
};
// More operator classes (contributed by Daryle Walker) --------------------//
template <class T, class U, class B = ::boost::detail::empty_base>
struct left_shiftable2 : B
{
friend T operator<<(T x, const U& y) { return x <<= y; }
};
template <class T, class B = ::boost::detail::empty_base>
struct left_shiftable1 : B
{
friend T operator<<(T x, const T& y) { return x <<= y; }
};
template <class T, class U, class B = ::boost::detail::empty_base>
struct right_shiftable2 : B
{
friend T operator>>(T x, const U& y) { return x >>= y; }
};
template <class T, class B = ::boost::detail::empty_base>
struct right_shiftable1 : B
{
friend T operator>>(T x, const T& y) { return x >>= y; }
};
template <class T, class U, class B = ::boost::detail::empty_base>
struct equivalent2 : B
{
friend bool operator==(const T& x, const U& y)
{
return !(x < y) && !(x > y);
}
};
template <class T, class B = ::boost::detail::empty_base>
struct equivalent1 : B
{
friend bool operator==(const T&x, const T&y)
{
return !(x < y) && !(y < x);
}
};
template <class T, class U, class B = ::boost::detail::empty_base>
struct partially_ordered2 : B
{
friend bool operator<=(const T& x, const U& y)
{ return (x < y) || (x == y); }
friend bool operator>=(const T& x, const U& y)
{ return (x > y) || (x == y); }
friend bool operator>(const U& x, const T& y)
{ return y < x; }
friend bool operator<(const U& x, const T& y)
{ return y > x; }
friend bool operator<=(const U& x, const T& y)
{ return (y > x) || (y == x); }
friend bool operator>=(const U& x, const T& y)
{ return (y < x) || (y == x); }
};
template <class T, class B = ::boost::detail::empty_base>
struct partially_ordered1 : B
{
friend bool operator>(const T& x, const T& y)
{ return y < x; }
friend bool operator<=(const T& x, const T& y)
{ return (x < y) || (x == y); }
friend bool operator>=(const T& x, const T& y)
{ return (y < x) || (x == y); }
};
// Combined operator classes (contributed by Daryle Walker) ----------------//
template <class T, class U, class B = ::boost::detail::empty_base>
struct totally_ordered2
: less_than_comparable2<T, U
, equality_comparable2<T, U, B
> > {};
template <class T, class B = ::boost::detail::empty_base>
struct totally_ordered1
: less_than_comparable1<T
, equality_comparable1<T, B
> > {};
template <class T, class U, class B = ::boost::detail::empty_base>
struct additive2
: addable2<T, U
, subtractable2<T, U, B
> > {};
template <class T, class B = ::boost::detail::empty_base>
struct additive1
: addable1<T
, subtractable1<T, B
> > {};
template <class T, class U, class B = ::boost::detail::empty_base>
struct multiplicative2
: multipliable2<T, U
, dividable2<T, U, B
> > {};
template <class T, class B = ::boost::detail::empty_base>
struct multiplicative1
: multipliable1<T
, dividable1<T, B
> > {};
template <class T, class U, class B = ::boost::detail::empty_base>
struct integer_multiplicative2
: multiplicative2<T, U
, modable2<T, U, B
> > {};
template <class T, class B = ::boost::detail::empty_base>
struct integer_multiplicative1
: multiplicative1<T
, modable1<T, B
> > {};
template <class T, class U, class B = ::boost::detail::empty_base>
struct arithmetic2
: additive2<T, U
, multiplicative2<T, U, B
> > {};
template <class T, class B = ::boost::detail::empty_base>
struct arithmetic1
: additive1<T
, multiplicative1<T, B
> > {};
template <class T, class U, class B = ::boost::detail::empty_base>
struct integer_arithmetic2
: additive2<T, U
, integer_multiplicative2<T, U, B
> > {};
template <class T, class B = ::boost::detail::empty_base>
struct integer_arithmetic1
: additive1<T
, integer_multiplicative1<T, B
> > {};
template <class T, class U, class B = ::boost::detail::empty_base>
struct bitwise2
: xorable2<T, U
, andable2<T, U
, orable2<T, U, B
> > > {};
template <class T, class B = ::boost::detail::empty_base>
struct bitwise1
: xorable1<T
, andable1<T
, orable1<T, B
> > > {};
template <class T, class B = ::boost::detail::empty_base>
struct unit_steppable
: incrementable<T
, decrementable<T, B
> > {};
template <class T, class U, class B = ::boost::detail::empty_base>
struct shiftable2
: left_shiftable2<T, U
, right_shiftable2<T, U, B
> > {};
template <class T, class B = ::boost::detail::empty_base>
struct shiftable1
: left_shiftable1<T
, right_shiftable1<T, B
> > {};
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
} // namespace boost
#endif // BOOST_NO_OPERATORS_IN_NAMESPACE
// BOOST_IMPORT_TEMPLATE1 .. BOOST_IMPORT_TEMPLATE3 -
//
// 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
// for one-argument forms of operator templates; BOOST_IMPORT_TEMPLATE2 for
// two-argument forms. Note that these macros expect to be invoked from within
// boost.
#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE
// The template is already in boost so we have nothing to do.
# define BOOST_IMPORT_TEMPLATE3(template_name)
# define BOOST_IMPORT_TEMPLATE2(template_name)
# define BOOST_IMPORT_TEMPLATE1(template_name)
#else // BOOST_NO_OPERATORS_IN_NAMESPACE
# ifndef BOOST_NO_USING_TEMPLATE
// Bring the names in with a using-declaration
// to avoid stressing the compiler.
# define BOOST_IMPORT_TEMPLATE3(template_name) using ::template_name;
# define BOOST_IMPORT_TEMPLATE2(template_name) using ::template_name;
# define BOOST_IMPORT_TEMPLATE1(template_name) using ::template_name;
# else
// Otherwise, because a Borland C++ 5.5 bug prevents a using declaration
// from working, we are forced to use inheritance for that compiler.
# define BOOST_IMPORT_TEMPLATE3(template_name) \
template <class T, class U, class V, class B = ::boost::detail::empty_base> \
struct template_name : ::template_name<T, U, V, B> {};
# define BOOST_IMPORT_TEMPLATE2(template_name) \
template <class T, class U, class B = ::boost::detail::empty_base> \
struct template_name : ::template_name<T, U, B> {};
# define BOOST_IMPORT_TEMPLATE1(template_name) \
template <class T, class B = ::boost::detail::empty_base> \
struct template_name : ::template_name<T, B> {};
# endif // BOOST_NO_USING_TEMPLATE
#endif // BOOST_NO_OPERATORS_IN_NAMESPACE
//
// Here's where we put it all together, defining the xxxx forms of the templates
// in namespace boost. We also define specializations of is_chained_base<> for
// the xxxx, xxxx1, and xxxx2 templates, importing them into boost:: as
// neccessary.
//
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
// is_chained_base<> - a traits class used to distinguish whether an operator
// template argument is being used for base class chaining, or is specifying a
// 2nd argument type.
namespace boost {
// A type parameter is used instead of a plain bool because Borland's compiler
// didn't cope well with the more obvious non-type template parameter.
namespace detail {
struct true_t {};
struct false_t {};
} // namespace detail
// Unspecialized version assumes that most types are not being used for base
// class chaining. We specialize for the operator templates defined in this
// library.
template<class T> struct is_chained_base {
typedef ::boost::detail::false_t value;
};
} // namespace boost
// Import a 3-type-argument operator template into boost (if neccessary) and
// provide a specialization of 'is_chained_base<>' for it.
# define BOOST_OPERATOR_TEMPLATE3(template_name3) \
BOOST_IMPORT_TEMPLATE3(template_name3) \
template<class T, class U, class V, class B> \
struct is_chained_base< ::boost::template_name3<T, U, V, B> > { \
typedef ::boost::detail::true_t value; \
};
// Import a 2-type-argument operator template into boost (if neccessary) and
// provide a specialization of 'is_chained_base<>' for it.
# define BOOST_OPERATOR_TEMPLATE2(template_name2) \
BOOST_IMPORT_TEMPLATE2(template_name2) \
template<class T, class U, class B> \
struct is_chained_base< ::boost::template_name2<T, U, B> > { \
typedef ::boost::detail::true_t value; \
};
// Import a 1-type-argument operator template into boost (if neccessary) and
// provide a specialization of 'is_chained_base<>' for it.
# define BOOST_OPERATOR_TEMPLATE1(template_name1) \
BOOST_IMPORT_TEMPLATE1(template_name1) \
template<class T, class B> \
struct is_chained_base< ::boost::template_name1<T, B> > { \
typedef ::boost::detail::true_t value; \
};
// BOOST_OPERATOR_TEMPLATE(template_name) defines template_name<> such that it
// can be used for specifying both 1-argument and 2-argument forms. Requires the
// existence of two previously defined class templates named '<template_name>1'
// and '<template_name>2' which must implement the corresponding 1- and 2-
// argument forms.
//
// The template type parameter O == is_chained_base<U>::value is used to
// distinguish whether the 2nd argument to <template_name> is being used for
// base class chaining from another boost operator template or is describing a
// 2nd operand type. O == true_t only when U is actually an another operator
// template from the library. Partial specialization is used to select an
// implementation in terms of either '<template_name>1' or '<template_name>2'.
//
# define BOOST_OPERATOR_TEMPLATE(template_name) \
template <class T \
,class U = T \
,class B = ::boost::detail::empty_base \
,class O = typename is_chained_base<U>::value \
> \
struct template_name : template_name##2<T, U, B> {}; \
\
template<class T, class U, class B> \
struct template_name<T, U, B, ::boost::detail::true_t> \
: template_name##1<T, U> {}; \
\
template <class T, class B> \
struct template_name<T, T, B, ::boost::detail::false_t> \
: template_name##1<T, B> {}; \
\
template<class T, class U, class B, class O> \
struct is_chained_base< ::boost::template_name<T, U, B, O> > { \
typedef ::boost::detail::true_t value; \
}; \
\
BOOST_OPERATOR_TEMPLATE2(template_name##2) \
BOOST_OPERATOR_TEMPLATE1(template_name##1)
#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
# define BOOST_OPERATOR_TEMPLATE3(template_name3) \
BOOST_IMPORT_TEMPLATE3(template_name3)
# define BOOST_OPERATOR_TEMPLATE2(template_name2) \
BOOST_IMPORT_TEMPLATE2(template_name2)
# define BOOST_OPERATOR_TEMPLATE1(template_name1) \
BOOST_IMPORT_TEMPLATE1(template_name1)
// In this case we can only assume that template_name<> is equivalent to the
// more commonly needed template_name1<> form.
# define BOOST_OPERATOR_TEMPLATE(template_name) \
template <class T, class B = ::boost::detail::empty_base> \
struct template_name : template_name##1<T, B> {};
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
namespace boost {
BOOST_OPERATOR_TEMPLATE(less_than_comparable)
BOOST_OPERATOR_TEMPLATE(equality_comparable)
BOOST_OPERATOR_TEMPLATE(multipliable)
BOOST_OPERATOR_TEMPLATE(addable)
BOOST_OPERATOR_TEMPLATE(subtractable)
BOOST_OPERATOR_TEMPLATE(dividable)
BOOST_OPERATOR_TEMPLATE(modable)
BOOST_OPERATOR_TEMPLATE(xorable)
BOOST_OPERATOR_TEMPLATE(andable)
BOOST_OPERATOR_TEMPLATE(orable)
BOOST_OPERATOR_TEMPLATE1(incrementable)
BOOST_OPERATOR_TEMPLATE1(decrementable)
BOOST_OPERATOR_TEMPLATE2(dereferenceable)
BOOST_OPERATOR_TEMPLATE3(indexable)
BOOST_OPERATOR_TEMPLATE(left_shiftable)
BOOST_OPERATOR_TEMPLATE(right_shiftable)
BOOST_OPERATOR_TEMPLATE(equivalent)
BOOST_OPERATOR_TEMPLATE(partially_ordered)
BOOST_OPERATOR_TEMPLATE(totally_ordered)
BOOST_OPERATOR_TEMPLATE(additive)
BOOST_OPERATOR_TEMPLATE(multiplicative)
BOOST_OPERATOR_TEMPLATE(integer_multiplicative)
BOOST_OPERATOR_TEMPLATE(arithmetic)
BOOST_OPERATOR_TEMPLATE(integer_arithmetic)
BOOST_OPERATOR_TEMPLATE(bitwise)
BOOST_OPERATOR_TEMPLATE1(unit_steppable)
BOOST_OPERATOR_TEMPLATE(shiftable)
#undef BOOST_OPERATOR_TEMPLATE
#undef BOOST_OPERATOR_TEMPLATE3
#undef BOOST_OPERATOR_TEMPLATE2
#undef BOOST_OPERATOR_TEMPLATE1
#undef BOOST_IMPORT_TEMPLATE1
#undef BOOST_IMPORT_TEMPLATE2
#undef BOOST_IMPORT_TEMPLATE3
// The following 'operators' classes can only be used portably if the derived class
// declares ALL of the required member operators.
template <class T, class U>
struct operators2
: totally_ordered2<T,U
, integer_arithmetic2<T,U
, bitwise2<T,U
> > > {};
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class T, class U = T>
struct operators : operators2<T, U> {};
template <class T> struct operators<T, T>
#else
template <class T> struct operators
#endif
: totally_ordered<T
, integer_arithmetic<T
, bitwise<T
, unit_steppable<T
> > > > {};
// Iterator helper classes (contributed by Jeremy Siek) -------------------//
// (Input and output iterator helpers contributed by Daryle Walker) -------//
// (Changed to use combined operator classes by Daryle Walker) ------------//
template <class T,
class V,
class D = std::ptrdiff_t,
class P = V const *,
class R = V const &>
struct input_iterator_helper
: equality_comparable1<T
, incrementable<T
, dereferenceable<T, P
, boost::iterator<std::input_iterator_tag, V, D, P, R
> > > > {};
template<class Derived>
struct output_iterator_helper
: boost::incrementable<Derived
, boost::iterator<std::output_iterator_tag, void, void, void, void
> >
{
Derived& operator*() { return static_cast<Derived&>(*this); }
Derived& operator++() { return static_cast<Derived&>(*this); }
};
template <class T,
class V,
class D = std::ptrdiff_t,
class P = V*,
class R = V&>
struct forward_iterator_helper
: equality_comparable1<T
, incrementable<T
, dereferenceable<T, P
, boost::iterator<std::forward_iterator_tag, V, D, P, R
> > > > {};
template <class T,
class V,
class D = std::ptrdiff_t,
class P = V*,
class R = V&>
struct bidirectional_iterator_helper
: equality_comparable1<T
, unit_steppable<T
, dereferenceable<T, P
, boost::iterator<std::bidirectional_iterator_tag, V, D, P, R
> > > > {};
template <class T,
class V,
class D = std::ptrdiff_t,
class P = V*,
class R = V&>
struct random_access_iterator_helper
: totally_ordered1<T
, unit_steppable<T
, dereferenceable<T, P
, additive2<T, D
, indexable<T, D, R
, boost::iterator<std::random_access_iterator_tag, V, D, P, R
> > > > > >
{
friend D requires_difference_operator(const T& x, const T& y) {
return x - y;
}
}; // random_access_iterator_helper
} // namespace boost
#if defined(__sgi) && !defined(__GNUC__)
#pragma reset woff 1234
#endif
#endif // BOOST_OPERATORS_HPP

119
include/boost/utility.hpp Normal file
View File

@@ -0,0 +1,119 @@
// boost utility.hpp header file -------------------------------------------//
// (C) Copyright boost.org 1999. Permission to copy, use, modify, sell
// and distribute this software is granted provided this copyright
// notice appears in all copies. This software is provided "as is" without
// express or implied warranty, and with no claim as to its suitability for
// any purpose.
// See http://www.boost.org for most recent version including documentation.
// Classes appear in alphabetical order
// Revision History
// 21 May 01 checked_delete() and checked_array_delete() added (Beman Dawes,
// suggested by Dave Abrahams, generalizing idea from Vladimir Prus)
// 21 May 01 made next() and prior() inline (Beman Dawes)
// 26 Jan 00 protected noncopyable destructor added (Miki Jovanovic)
// 10 Dec 99 next() and prior() templates added (Dave Abrahams)
// 30 Aug 99 moved cast templates to cast.hpp (Beman Dawes)
// 3 Aug 99 cast templates added
// 20 Jul 99 name changed to utility.hpp
// 9 Jun 99 protected noncopyable default ctor
// 2 Jun 99 Initial Version. Class noncopyable only contents (Dave Abrahams)
#ifndef BOOST_UTILITY_HPP
#define BOOST_UTILITY_HPP
#include <boost/config.hpp> // broken compiler workarounds
#include <boost/static_assert.hpp>
#include <cstddef> // for size_t
#include <utility> // for std::pair
namespace boost
{
// checked_delete() and checked_array_delete() -----------------------------//
// verify that types are complete for increased safety
template< typename T >
inline void checked_delete(T * x)
{
BOOST_STATIC_ASSERT( sizeof(T) != 0 ); // assert type complete at point
// of instantiation
delete x;
}
template< typename T >
inline void checked_array_delete(T * x)
{
BOOST_STATIC_ASSERT( sizeof(T) != 0 ); // assert type complete at point
// of instantiation
delete [] x;
}
// next() and prior() template functions -----------------------------------//
// Helper functions for classes like bidirectional iterators not supporting
// operator+ and operator-.
//
// Usage:
// const std::list<T>::iterator p = get_some_iterator();
// const std::list<T>::iterator prev = boost::prior(p);
// Contributed by Dave Abrahams
template <class T>
inline T next(T x) { return ++x; }
template <class T>
inline T prior(T x) { return --x; }
// class noncopyable -------------------------------------------------------//
// Private copy constructor and copy assignment ensure classes derived from
// class noncopyable cannot be copied.
// Contributed by Dave Abrahams
class noncopyable
{
protected:
noncopyable(){}
~noncopyable(){}
private: // emphasize the following members are private
noncopyable( const noncopyable& );
const noncopyable& operator=( const noncopyable& );
}; // noncopyable
// class tied -------------------------------------------------------//
// A helper for conveniently assigning the two values from a pair
// into separate variables. The idea for this comes from Jaakko J<>rvi's
// Binder/Lambda Library.
// Constributed by Jeremy Siek
template <class A, class B>
class tied {
public:
inline tied(A& a, B& b) : _a(a), _b(b) { }
template <class U, class V>
inline tied& operator=(const std::pair<U,V>& p) {
_a = p.first;
_b = p.second;
return *this;
}
protected:
A& _a;
B& _b;
};
template <class A, class B>
inline tied<A,B> tie(A& a, B& b) { return tied<A,B>(a, b); }
} // namespace boost
#endif // BOOST_UTILITY_HPP

View File

@@ -93,7 +93,7 @@
<a href="function_output_iterator.htm">Function Output Iterator Adaptor</a>
</ul>
<p><b><a href="http://www.boost.org/people/dave_abrahams.htm">Dave
<p><b><a href="file:///c:/boost/site/people/dave_abrahams.htm">Dave
Abrahams</a></b> started the library, applying <a href=
"../../more/generic_programming.html#policy">policy class</a> technique and
handling const/non-const iterator interactions. He also contributed the
@@ -102,7 +102,7 @@
<tt><a href="counting_iterator.htm">counting_iterator_generator</a></tt> to
cover all incrementable types. He edited most of the documentation,
sometimes heavily.<br>
<b><a href="http://www.boost.org/people/jeremy_siek.htm">Jeremy
<b><a href="file:///c:/boost/site/people/jeremy_siek.htm">Jeremy
Siek</a></b> contributed the <a href="transform_iterator.htm">transform
iterator</a> adaptor, the integer-only version of <tt><a href=
"counting_iterator.htm">counting_iterator_generator</a></tt>,
@@ -860,7 +860,7 @@ bool operator==(const iterator_adaptor&lt;B1,P,V1,R1,P1,C,D&gt;&amp;,
<hr>
<p>Revised
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->19 Mar 2001<!--webbot bot="Timestamp" endspan i-checksum="14895" -->
<!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->12 Jul 2001<!--webbot bot="Timestamp" endspan i-checksum="14985" -->
<p>&copy; Copyright Dave Abrahams and Jeremy Siek 2001. Permission to copy,

View File

@@ -9,16 +9,29 @@
// See http://www.boost.org for most recent version including documentation.
// Revision History
// 29 May 01 Factored implementation, added comparison tests, use Test Tools
// library (Daryle Walker)
// 12 Dec 99 Initial version with iterator operators (Jeremy Siek)
#include <string>
#include <iostream>
using namespace std;
#define BOOST_INCLUDE_MAIN
#include <boost/test/test_tools.hpp> // for main
#include <boost/operators.hpp>
using namespace boost;
#include <boost/config.hpp> // for BOOST_STATIC_CONSTANT
#include <boost/cstdlib.hpp> // for boost::exit_success
#include <boost/operators.hpp> // for boost::random_access_iterator_helper
#include <cstddef> // for std::ptrdiff_t, std::size_t
#include <cstring> // for std::strcmp
#include <iostream> // for std::cout (std::endl, ends, and flush indirectly)
#include <string> // for std::string
#include <strstream> // for std::ostrstream
# ifdef BOOST_NO_STDC_NAMESPACE
namespace std { using ::strcmp; }
# endif
// Iterator test class
template <class T, class R, class P>
struct test_iter
: public boost::random_access_iterator_helper<
@@ -29,7 +42,7 @@ struct test_iter
typedef std::ptrdiff_t Distance;
public:
test_iter(T* i) : _i(i) { }
explicit test_iter(T* i =0) : _i(i) { }
test_iter(const self& x) : _i(x._i) { }
self& operator=(const self& x) { _i = x._i; return *this; }
Reference operator*() const { return *_i; }
@@ -43,127 +56,280 @@ public:
return x._i - y._i;
}
protected:
T* _i;
P _i;
};
int
main()
// Iterator operator testing classes
class test_opr_base
{
string array[] = { "apple", "orange", "pear", "peach", "grape", "plum" };
{
test_iter<string,string&,string*> i = array,
ie = array + sizeof(array)/sizeof(string);
protected:
// Test data and types
BOOST_STATIC_CONSTANT( std::size_t, fruit_length = 6u );
BOOST_STATIC_CONSTANT( std::size_t, scratch_length = 40u );
// Tests for all of the operators added by random_access_iterator_helper
typedef std::string fruit_array_type[ fruit_length ];
typedef char scratch_array_type[ scratch_length ];
// test i++
while (i != ie)
cout << *i++ << " ";
cout << endl;
i = array;
static fruit_array_type fruit;
static scratch_array_type scratch;
// test i--
while (ie != i) {
ie--;
cout << *ie << " ";
}
cout << endl;
ie = array + sizeof(array)/sizeof(string);
}; // test_opr_base
// test i->m
while (i != ie) {
cout << i->size() << " ";
++i;
}
cout << endl;
i = array;
template <typename T, typename R = T&, typename P = T*>
class test_opr
: public test_opr_base
{
typedef test_opr<T, R, P> self_type;
// test i + n
while (i < ie) {
cout << *i << " ";
i = i + 2;
}
cout << endl;
i = array;
public:
// Types
typedef T value_type;
typedef R reference;
typedef P pointer;
// test n + i
while (i < ie) {
cout << *i << " ";
i = ptrdiff_t(2) + i;
}
cout << endl;
i = array;
typedef test_iter<T, R, P> iter_type;
// test i - n
while (ie > i) {
ie = ie - 2;
cout << *ie << " ";
}
cout << endl;
ie = array + sizeof(array)/sizeof(string);
// Test controller
static void master_test( char const name[] );
// test i[n]
for (std::size_t j = 0; j < sizeof(array)/sizeof(string); ++j)
cout << i[j] << " ";
cout << endl;
}
{
test_iter<string, const string&, const string*> i = array,
ie = array + sizeof(array)/sizeof(string);
private:
// Test data
static iter_type const fruit_begin, fruit_end;
// Tests for all of the operators added by random_access_iterator_helper
// 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 i++
while (i != ie)
cout << *i++ << " ";
cout << endl;
i = array;
}; // test_opr
// test i--
while (ie != i) {
ie--;
cout << *ie << " ";
}
cout << endl;
ie = array + sizeof(array)/sizeof(string);
// test i->m
while (i != ie) {
cout << i->size() << " ";
++i;
}
cout << endl;
i = array;
// Class-static data definitions
test_opr_base::fruit_array_type
test_opr_base::fruit = { "apple", "orange", "pear", "peach", "grape", "plum" };
// test i + n
while (i < ie) {
cout << *i << " ";
i = i + 2;
}
cout << endl;
i = array;
test_opr_base::scratch_array_type
test_opr_base::scratch = "";
// test n + i
while (i < ie) {
cout << *i << " ";
i = ptrdiff_t(2) + i;
}
cout << endl;
i = array;
template <typename T, typename R, typename P>
typename test_opr<T, R, P>::iter_type const
test_opr<T, R, P>::fruit_begin( fruit );
// test i - n
while (ie > i) {
ie = ie - 2;
cout << *ie << " ";
}
cout << endl;
ie = array + sizeof(array)/sizeof(string);
template <typename T, typename R, typename P>
typename test_opr<T, R, P>::iter_type const
test_opr<T, R, P>::fruit_end( fruit + fruit_length );
// test i[n]
for (std::size_t j = 0; j < sizeof(array)/sizeof(string); ++j)
cout << i[j] << " ";
cout << endl;
}
return 0;
// Main testing function
int
test_main( int , char * [] )
{
using std::string;
typedef test_opr<string, string &, string *> test1_type;
typedef test_opr<string, string const &, string const *> test2_type;
test1_type::master_test( "non-const string" );
test2_type::master_test( "const string" );
return boost::exit_success;
}
// Tests for all of the operators added by random_access_iterator_helper
template <typename T, typename R, typename P>
void
test_opr<T, R, P>::master_test
(
char const name[]
)
{
std::cout << "Doing test run for " << name << '.' << std::endl;
post_increment_test();
post_decrement_test();
indirect_referral_test();
offset_addition_test();
reverse_offset_addition_test();
offset_subtraction_test();
comparison_test();
indexing_test();
}
// Test post-increment
template <typename T, typename R, typename P>
void
test_opr<T, R, P>::post_increment_test
(
)
{
std::cout << "\tDoing post-increment test." << std::endl;
std::ostrstream oss( scratch, scratch_length );
for ( iter_type i = fruit_begin ; i != fruit_end ; )
{
oss << *i++ << ' ';
}
oss << std::ends;
BOOST_TEST( std::strcmp(oss.str(), "apple orange pear peach grape plum ")
== 0 );
}
// Test post-decrement
template <typename T, typename R, typename P>
void
test_opr<T, R, P>::post_decrement_test
(
)
{
std::cout << "\tDoing post-decrement test." << std::endl;
std::ostrstream oss( scratch, scratch_length );
for ( iter_type i = fruit_end ; i != fruit_begin ; )
{
i--;
oss << *i << ' ';
}
oss << std::ends;
BOOST_TEST( std::strcmp(oss.str(), "plum grape peach pear orange apple ")
== 0 );
}
// Test indirect structure referral
template <typename T, typename R, typename P>
void
test_opr<T, R, P>::indirect_referral_test
(
)
{
std::cout << "\tDoing indirect reference test." << std::endl;
std::ostrstream oss( scratch, scratch_length );
for ( iter_type i = fruit_begin ; i != fruit_end ; ++i )
{
oss << i->size() << ' ';
}
oss << std::ends;
BOOST_TEST( std::strcmp(oss.str(), "5 6 4 5 5 4 ") == 0 );
}
// Test offset addition
template <typename T, typename R, typename P>
void
test_opr<T, R, P>::offset_addition_test
(
)
{
std::cout << "\tDoing offset addition test." << std::endl;
std::ptrdiff_t const two = 2;
std::ostrstream oss( scratch, scratch_length );
for ( iter_type i = fruit_begin ; i != fruit_end ; i = i + two )
{
oss << *i << ' ';
}
oss << std::ends;
BOOST_TEST( std::strcmp(oss.str(), "apple pear grape ") == 0 );
}
// Test offset addition, in reverse order
template <typename T, typename R, typename P>
void
test_opr<T, R, P>::reverse_offset_addition_test
(
)
{
std::cout << "\tDoing reverse offset addition test." << std::endl;
std::ptrdiff_t const two = 2;
std::ostrstream oss( scratch, scratch_length );
for ( iter_type i = fruit_begin ; i != fruit_end ; i = two + i )
{
oss << *i << ' ';
}
oss << std::ends;
BOOST_TEST( std::strcmp(oss.str(), "apple pear grape ") == 0 );
}
// Test offset subtraction
template <typename T, typename R, typename P>
void
test_opr<T, R, P>::offset_subtraction_test
(
)
{
std::cout << "\tDoing offset subtraction test." << std::endl;
std::ptrdiff_t const two = 2;
std::ostrstream oss( scratch, scratch_length );
for ( iter_type i = fruit_end ; fruit_begin < i ; )
{
i = i - two;
if ( (fruit_begin < i) || (fruit_begin == i) )
{
oss << *i << ' ';
}
}
oss << std::ends;
BOOST_TEST( std::strcmp(oss.str(), "grape pear apple ") == 0 );
}
// Test comparisons
template <typename T, typename R, typename P>
void
test_opr<T, R, P>::comparison_test
(
)
{
using std::cout;
using std::ptrdiff_t;
cout << "\tDoing comparison tests.\n\t\tPass:";
for ( iter_type i = fruit_begin ; i != fruit_end ; ++i )
{
ptrdiff_t const i_offset = i - fruit_begin;
cout << ' ' << *i << std::flush;
for ( iter_type j = fruit_begin ; j != fruit_end ; ++j )
{
ptrdiff_t const j_offset = j - fruit_begin;
BOOST_TEST( (i != j) == (i_offset != j_offset) );
BOOST_TEST( (i > j) == (i_offset > j_offset) );
BOOST_TEST( (i <= j) == (i_offset <= j_offset) );
BOOST_TEST( (i >= j) == (i_offset >= j_offset) );
}
}
cout << std::endl;
}
// Test indexing
template <typename T, typename R, typename P>
void
test_opr<T, R, P>::indexing_test
(
)
{
std::cout << "\tDoing indexing test." << std::endl;
std::ostrstream oss( scratch, scratch_length );
for ( std::size_t k = 0u ; k < fruit_length ; ++k )
{
oss << fruit_begin[ k ] << ' ';
}
oss << std::ends;
BOOST_TEST( std::strcmp(oss.str(), "apple orange pear peach grape plum ")
== 0 );
}

View File

@@ -7,6 +7,7 @@
// See http://www.boost.org for most recent version including documentation.
// Revision History
// 1 Apr 2001 Fixes for ICL; use BOOST_STATIC_CONSTANT
// 11 Feb 2001 Fixes for Borland (David Abrahams)
// 23 Jan 2001 Added test for wchar_t (David Abrahams)
// 23 Jan 2001 Now statically selecting a test for signed numbers to avoid
@@ -30,13 +31,6 @@
# include <limits>
#endif
// A macro for declaring class compile-time constants.
#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
# define DECLARE_CLASS_CONST(type, init) static const type init
#else
# define DECLARE_CLASS_CONST(type, init) enum { init }
#endif
// =================================================================================
// template class complement_traits<Number> --
//
@@ -53,8 +47,8 @@ template <unsigned size> struct complement; // forward
template <class Number, unsigned size>
struct complement_traits_aux
{
DECLARE_CLASS_CONST(Number, max = complement<size>::template traits<Number>::max);
DECLARE_CLASS_CONST(Number, min = complement<size>::template traits<Number>::min);
BOOST_STATIC_CONSTANT(Number, max = complement<size>::template traits<Number>::max);
BOOST_STATIC_CONSTANT(Number, min = complement<size>::template traits<Number>::min);
};
template <unsigned size>
@@ -67,11 +61,11 @@ struct complement
// indirection through complement_traits_aux neccessary to keep MSVC happy
typedef complement_traits_aux<Number, size - 1> prev;
public:
DECLARE_CLASS_CONST(Number, max =
BOOST_STATIC_CONSTANT(Number, max =
Number(Number(prev::max) << CHAR_BIT)
+ Number(UCHAR_MAX));
DECLARE_CLASS_CONST(Number, min = Number(Number(prev::min) << CHAR_BIT));
BOOST_STATIC_CONSTANT(Number, min = Number(Number(prev::min) << CHAR_BIT));
};
};
@@ -85,8 +79,8 @@ template <> struct complement_base<false>
template <class Number>
struct values
{
DECLARE_CLASS_CONST(Number, min = 0);
DECLARE_CLASS_CONST(Number, max = UCHAR_MAX);
BOOST_STATIC_CONSTANT(Number, min = 0);
BOOST_STATIC_CONSTANT(Number, max = UCHAR_MAX);
};
};
@@ -95,8 +89,8 @@ template <> struct complement_base<true>
template <class Number>
struct values
{
DECLARE_CLASS_CONST(Number, min = SCHAR_MIN);
DECLARE_CLASS_CONST(Number, max = SCHAR_MAX);
BOOST_STATIC_CONSTANT(Number, min = SCHAR_MIN);
BOOST_STATIC_CONSTANT(Number, max = SCHAR_MAX);
};
};
@@ -107,10 +101,10 @@ struct complement<1>
template <class Number>
struct traits
{
DECLARE_CLASS_CONST(bool, is_signed = boost::detail::is_signed<Number>::value);
DECLARE_CLASS_CONST(Number, min =
BOOST_STATIC_CONSTANT(bool, is_signed = boost::detail::is_signed<Number>::value);
BOOST_STATIC_CONSTANT(Number, min =
complement_base<is_signed>::template values<Number>::min);
DECLARE_CLASS_CONST(Number, max =
BOOST_STATIC_CONSTANT(Number, max =
complement_base<is_signed>::template values<Number>::max);
};
};
@@ -121,8 +115,8 @@ struct complement<1>
template <class Number>
struct complement_traits
{
DECLARE_CLASS_CONST(Number, max = (complement_traits_aux<Number, sizeof(Number)>::max));
DECLARE_CLASS_CONST(Number, min = (complement_traits_aux<Number, sizeof(Number)>::min));
BOOST_STATIC_CONSTANT(Number, max = (complement_traits_aux<Number, sizeof(Number)>::max));
BOOST_STATIC_CONSTANT(Number, min = (complement_traits_aux<Number, sizeof(Number)>::min));
};
// =================================================================================
@@ -151,9 +145,9 @@ template <> struct stream_as<signed char> {
typedef unsigned char t1; typedef unsigned t2;
};
#if defined(BOOST_MSVC) // No intmax streaming built-in
#if defined(BOOST_MSVC_STD_ITERATOR) // No intmax streaming built-in
// On this platform, __int64 and __uint64 get streamed as strings
// With this library implementation, __int64 and __uint64 get streamed as strings
template <> struct stream_as<boost::uintmax_t> {
typedef std::string t1;
typedef std::string t2;
@@ -174,7 +168,7 @@ template <class T> struct promote
}
};
#if defined(BOOST_MSVC) // No intmax streaming built-in
#if defined(BOOST_MSVC_STD_ITERATOR) // No intmax streaming built-in
// On this platform, stream them as long/unsigned long if they fit.
// Otherwise, write a string.

File diff suppressed because it is too large Load Diff

View File

@@ -8,18 +8,26 @@
// See http://www.boost.org for most recent version including documentation.
// Revision History
// 20 May 01 Output progress messages. Added tests for new operator
// templates. Updated random number generator. Changed tests to
// use Boost Test Tools library. (Daryle Walker)
// 04 Jun 00 Added regression test for a bug I found (David Abrahams)
// 17 Jun 00 Fix for broken compilers (Aleksey Gurtovoy)
// ?? ??? 00 Major update to randomly test all one- and two- argument forms by
// wrapping integral types and comparing the results of operations to
// the results for the raw types (David Abrahams)
// wrapping integral types and comparing the results of operations
// to the results for the raw types (David Abrahams)
// 12 Dec 99 Minor update, output confirmation message.
// 15 Nov 99 Initial version
#include <boost/operators.hpp>
#include <cassert>
#include <iostream>
#include <boost/min_rand.hpp>
#define BOOST_INCLUDE_MAIN
#include <boost/config.hpp> // for BOOST_MSVC
#include <boost/cstdlib.hpp> // for boost::exit_success
#include <boost/operators.hpp> // for the tested items
#include <boost/random/linear_congruential.hpp> // for boost::minstd_rand
#include <boost/test/test_tools.hpp> // for main
#include <iostream> // for std::cout (std::endl indirectly)
namespace
@@ -28,14 +36,18 @@ namespace
int true_value(int x) { return x; }
long true_value(long x) { return x; }
signed char true_value(signed char x) { return x; }
short true_value(short x) { return x; }
unsigned int true_value(unsigned int x) { return x; }
unsigned long true_value(unsigned long x) { return x; }
unsigned char true_value(unsigned char x) { return x; }
unsigned short true_value(unsigned short x) { return x; }
// The use of operators<> here tended to obscure interactions with certain
// compiler bugs
// The use of operators<> here tended to obscure
// interactions with certain compiler bugs
template <class T>
class Wrapped1 : boost::operators<Wrapped1<T> >
class Wrapped1
: boost::operators<Wrapped1<T> >
, boost::shiftable<Wrapped1<T> >
{
public:
explicit Wrapped1( T v = T() ) : _value(v) {}
@@ -60,6 +72,10 @@ namespace
{ _value &= x._value; return *this; }
Wrapped1& operator^=(const Wrapped1& x)
{ _value ^= x._value; return *this; }
Wrapped1& operator<<=(const Wrapped1& x)
{ _value <<= x._value; return *this; }
Wrapped1& operator>>=(const Wrapped1& x)
{ _value >>= x._value; return *this; }
Wrapped1& operator++() { ++_value; return *this; }
Wrapped1& operator--() { --_value; return *this; }
@@ -70,9 +86,11 @@ namespace
T true_value(Wrapped1<T> x) { return x.value(); }
template <class T, class U>
class Wrapped2 :
boost::operators<Wrapped2<T, U> >,
boost::operators2<Wrapped2<T, U>, U>
class Wrapped2
: boost::operators<Wrapped2<T, U> >
, boost::operators2<Wrapped2<T, U>, U>
, boost::shiftable1<Wrapped2<T, U>
, boost::shiftable2<Wrapped2<T, U>, U > >
{
public:
explicit Wrapped2( T v = T() ) : _value(v) {}
@@ -97,6 +115,10 @@ namespace
{ _value &= x._value; return *this; }
Wrapped2& operator^=(const Wrapped2& x)
{ _value ^= x._value; return *this; }
Wrapped2& operator<<=(const Wrapped2& x)
{ _value <<= x._value; return *this; }
Wrapped2& operator>>=(const Wrapped2& x)
{ _value >>= x._value; return *this; }
Wrapped2& operator++() { ++_value; return *this; }
Wrapped2& operator--() { --_value; return *this; }
@@ -111,6 +133,8 @@ namespace
Wrapped2& operator|=(U u) { _value |= u; return *this; }
Wrapped2& operator&=(U u) { _value &= u; return *this; }
Wrapped2& operator^=(U u) { _value ^= u; return *this; }
Wrapped2& operator<<=(U u) { _value <<= u; return *this; }
Wrapped2& operator>>=(U u) { _value >>= u; return *this; }
private:
T _value;
@@ -118,203 +142,268 @@ namespace
template <class T, class U>
T true_value(Wrapped2<T,U> x) { return x.value(); }
template <class T>
class Wrapped3
: boost::equivalent<Wrapped3<T> >
, boost::partially_ordered<Wrapped3<T> >
, boost::equality_comparable<Wrapped3<T> >
{
public:
explicit Wrapped3( T v = T() ) : _value(v) {}
T value() const { return _value; }
bool operator<(const Wrapped3& x) const { return _value < x._value; }
private:
T _value;
};
template <class T>
T true_value(Wrapped3<T> x) { return x.value(); }
template <class T, class U>
class Wrapped4
: boost::equality_comparable1<Wrapped4<T, U>
, boost::equivalent1<Wrapped4<T, U>
, boost::partially_ordered1<Wrapped4<T, U> > > >
, boost::partially_ordered2<Wrapped4<T, U>, U
, boost::equivalent2<Wrapped4<T, U>, U
, boost::equality_comparable2<Wrapped4<T, U>, U> > >
{
public:
explicit Wrapped4( T v = T() ) : _value(v) {}
T value() const { return _value; }
bool operator<(const Wrapped4& x) const { return _value < x._value; }
bool operator<(U u) const { return _value < u; }
bool operator>(U u) const { return _value > u; }
private:
T _value;
};
template <class T, class U>
T true_value(Wrapped4<T,U> x) { return x.value(); }
// MyInt uses only the single template-argument form of all_operators<>
typedef Wrapped1<int> MyInt;
typedef Wrapped2<long, long> MyLong;
typedef Wrapped3<signed char> MyChar;
typedef Wrapped4<short, short> MyShort;
template <class X1, class Y1, class X2, class Y2>
void sanity_check(X1 x1, Y1 y1, X2 x2, Y2 y2)
{
assert(true_value(y1) == true_value(y2));
assert(true_value(x1) == true_value(x2));
BOOST_TEST( true_value(y1) == true_value(y2) );
BOOST_TEST( true_value(x1) == true_value(x2) );
}
template <class X1, class Y1, class X2, class Y2>
void test_less_than_comparable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
{
assert((x1 < y1) == (x2 < y2));
assert((x1 <= y1) == (x2 <= y2));
assert((x1 >= y1) == (x2 >= y2));
assert((x1 > y1) == (x2 > y2));
BOOST_TEST( (x1 < y1) == (x2 < y2) );
BOOST_TEST( (x1 <= y1) == (x2 <= y2) );
BOOST_TEST( (x1 >= y1) == (x2 >= y2) );
BOOST_TEST( (x1 > y1) == (x2 > y2) );
}
template <class X1, class Y1, class X2, class Y2>
void test_less_than_comparable(X1 x1, Y1 y1, X2 x2, Y2 y2)
{
sanity_check(x1, y1, x2, y2);
test_less_than_comparable_aux(x1, y1, x2, y2);
test_less_than_comparable_aux(y1, x1, y2, x2);
sanity_check( x1, y1, x2, y2 );
test_less_than_comparable_aux( x1, y1, x2, y2 );
test_less_than_comparable_aux( y1, x1, y2, x2 );
}
template <class X1, class Y1, class X2, class Y2>
void test_equality_comparable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
{
assert((x1 == y1) == (x2 == y2));
assert((x1 != y1) == (x2 != y2));
BOOST_TEST( (x1 == y1) == (x2 == y2) );
BOOST_TEST( (x1 != y1) == (x2 != y2) );
}
template <class X1, class Y1, class X2, class Y2>
void test_equality_comparable(X1 x1, Y1 y1, X2 x2, Y2 y2)
{
sanity_check(x1, y1, x2, y2);
test_equality_comparable_aux(x1, y1, x2, y2);
test_equality_comparable_aux(y1, x1, y2, x2);
sanity_check( x1, y1, x2, y2 );
test_equality_comparable_aux( x1, y1, x2, y2 );
test_equality_comparable_aux( y1, x1, y2, x2 );
}
template <class X1, class Y1, class X2, class Y2>
void test_multipliable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
{
assert((x1 * y1).value() == (x2 * y2));
BOOST_TEST( (x1 * y1).value() == (x2 * y2) );
}
template <class X1, class Y1, class X2, class Y2>
void test_multipliable(X1 x1, Y1 y1, X2 x2, Y2 y2)
{
sanity_check(x1, y1, x2, y2);
test_multipliable_aux(x1, y1, x2, y2);
test_multipliable_aux(y1, x1, y2, x2);
sanity_check( x1, y1, x2, y2 );
test_multipliable_aux( x1, y1, x2, y2 );
test_multipliable_aux( y1, x1, y2, x2 );
}
template <class X1, class Y1, class X2, class Y2>
void test_addable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
{
assert((x1 + y1).value() == (x2 + y2));
BOOST_TEST( (x1 + y1).value() == (x2 + y2) );
}
template <class X1, class Y1, class X2, class Y2>
void test_addable(X1 x1, Y1 y1, X2 x2, Y2 y2)
{
sanity_check(x1, y1, x2, y2);
test_addable_aux(x1, y1, x2, y2);
test_addable_aux(y1, x1, y2, x2);
sanity_check( x1, y1, x2, y2 );
test_addable_aux( x1, y1, x2, y2 );
test_addable_aux( y1, x1, y2, x2 );
}
template <class X1, class Y1, class X2, class Y2>
void test_subtractable(X1 x1, Y1 y1, X2 x2, Y2 y2)
{
sanity_check(x1, y1, x2, y2);
assert((x1 - y1).value() == x2 - 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_dividable(X1 x1, Y1 y1, X2 x2, Y2 y2)
{
sanity_check(x1, y1, x2, y2);
if (y2 != 0)
assert((x1 / y1).value() == x2 / y2);
sanity_check( x1, y1, x2, y2 );
if ( y2 != 0 )
BOOST_TEST( (x1 / y1).value() == (x2 / y2) );
}
template <class X1, class Y1, class X2, class Y2>
void test_modable(X1 x1, Y1 y1, X2 x2, Y2 y2)
{
sanity_check(x1, y1, x2, y2);
if (y2 != 0)
assert((x1 / y1).value() == x2 / y2);
sanity_check( x1, y1, x2, y2 );
if ( y2 != 0 )
BOOST_TEST( (x1 % y1).value() == (x2 % y2) );
}
template <class X1, class Y1, class X2, class Y2>
void test_xorable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
{
assert((x1 ^ y1).value() == (x2 ^ y2));
BOOST_TEST( (x1 ^ y1).value() == (x2 ^ y2) );
}
template <class X1, class Y1, class X2, class Y2>
void test_xorable(X1 x1, Y1 y1, X2 x2, Y2 y2)
{
sanity_check(x1, y1, x2, y2);
test_xorable_aux(x1, y1, x2, y2);
test_xorable_aux(y1, x1, y2, x2);
sanity_check( x1, y1, x2, y2 );
test_xorable_aux( x1, y1, x2, y2 );
test_xorable_aux( y1, x1, y2, x2 );
}
template <class X1, class Y1, class X2, class Y2>
void test_andable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
{
assert((x1 & y1).value() == (x2 & y2));
BOOST_TEST( (x1 & y1).value() == (x2 & y2) );
}
template <class X1, class Y1, class X2, class Y2>
void test_andable(X1 x1, Y1 y1, X2 x2, Y2 y2)
{
sanity_check(x1, y1, x2, y2);
test_andable_aux(x1, y1, x2, y2);
test_andable_aux(y1, x1, y2, x2);
sanity_check( x1, y1, x2, y2 );
test_andable_aux( x1, y1, x2, y2 );
test_andable_aux( y1, x1, y2, x2 );
}
template <class X1, class Y1, class X2, class Y2>
void test_orable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2)
{
assert((x1 | y1).value() == (x2 | y2));
BOOST_TEST( (x1 | y1).value() == (x2 | y2) );
}
template <class X1, class Y1, class X2, class Y2>
void test_orable(X1 x1, Y1 y1, X2 x2, Y2 y2)
{
sanity_check(x1, y1, x2, y2);
test_orable_aux(x1, y1, x2, y2);
test_orable_aux(y1, x1, y2, x2);
sanity_check( x1, y1, x2, y2 );
test_orable_aux( x1, y1, x2, y2 );
test_orable_aux( y1, x1, y2, x2 );
}
template <class X1, class Y1, class X2, class Y2>
void test_left_shiftable(X1 x1, Y1 y1, X2 x2, Y2 y2)
{
sanity_check( x1, y1, x2, y2 );
BOOST_TEST( (x1 << y1).value() == (x2 << y2) );
}
template <class X1, class Y1, class X2, class Y2>
void test_right_shiftable(X1 x1, Y1 y1, X2 x2, Y2 y2)
{
sanity_check( x1, y1, x2, y2 );
BOOST_TEST( (x1 >> y1).value() == (x2 >> y2) );
}
template <class X1, class X2>
void test_incrementable(X1 x1, X2 x2)
{
sanity_check(x1, x1, x2, x2);
assert(x1++.value() == x2++);
assert(x1.value() == x2);
sanity_check( x1, x1, x2, x2 );
BOOST_TEST( (x1++).value() == x2++ );
BOOST_TEST( x1.value() == x2 );
}
template <class X1, class X2>
void test_decrementable(X1 x1, X2 x2)
{
sanity_check(x1, x1, x2, x2);
assert(x1--.value() == x2--);
assert(x1.value() == x2);
sanity_check( x1, x1, x2, x2 );
BOOST_TEST( (x1--).value() == x2-- );
BOOST_TEST( x1.value() == x2 );
}
template <class X1, class Y1, class X2, class Y2>
void test_all(X1 x1, Y1 y1, X2 x2, Y2 y2)
{
test_less_than_comparable(x1, y1, x2, y2);
test_equality_comparable(x1, y1, x2, y2);
test_multipliable(x1, y1, x2, y2);
test_addable(x1, y1, x2, y2);
test_subtractable(x1, y1, x2, y2);
test_dividable(x1, y1, x2, y2);
test_modable(x1, y1, x2, y2);
test_xorable(x1, y1, x2, y2);
test_andable(x1, y1, x2, y2);
test_orable(x1, y1, x2, y2);
test_incrementable(x1, x2);
test_decrementable(x1, x2);
test_less_than_comparable( x1, y1, x2, y2 );
test_equality_comparable( x1, y1, x2, y2 );
test_multipliable( x1, y1, x2, y2 );
test_addable( x1, y1, x2, y2 );
test_subtractable( x1, y1, x2, y2 );
test_dividable( x1, y1, x2, y2 );
test_modable( x1, y1, x2, y2 );
test_xorable( x1, y1, x2, y2 );
test_andable( x1, y1, x2, y2 );
test_orable( x1, y1, x2, y2 );
test_left_shiftable( x1, y1, x2, y2 );
test_right_shiftable( x1, y1, x2, y2 );
test_incrementable( x1, x2 );
test_decrementable( x1, x2 );
}
template <class Big, class Small>
struct tester
{
void operator()(boost::min_rand& randomizer) const
void operator()(boost::minstd_rand& randomizer) const
{
Big b1 = Big(randomizer());
Big b2 = Big(randomizer());
Small s = Small(randomizer());
Big b1 = Big( randomizer() );
Big b2 = Big( randomizer() );
Small s = Small( randomizer() );
test_all(Wrapped1<Big>(b1), Wrapped1<Big>(b2), b1, b2);
test_all(Wrapped2<Big, Small>(b1), s, b1, s);
test_all( Wrapped1<Big>(b1), Wrapped1<Big>(b2), b1, b2 );
test_all( Wrapped2<Big, Small>(b1), s, b1, s );
}
};
// added as a regression test. We had a bug which this uncovered.
struct Point
: boost::addable<Point,
boost::subtractable<Point> >
: boost::addable<Point
, boost::subtractable<Point> >
{
Point( int h, int v ) : h(h), v(v) {}
Point() :h(0), v(0) {}
const Point& operator+=( const Point& rhs ) { h += rhs.h; v += rhs.v; return *this; }
const Point& operator-=( const Point& rhs ) { h -= rhs.h; v -= rhs.v; return *this; }
const Point& operator+=( const Point& rhs )
{ h += rhs.h; v += rhs.v; return *this; }
const Point& operator-=( const Point& rhs )
{ h -= rhs.h; v -= rhs.v; return *this; }
int h;
int v;
};
} // unnamed namespace
@@ -340,20 +429,25 @@ template Wrapped2<unsigned long, unsigned char>;
template Wrapped2<unsigned long, unsigned long>;
#endif
#ifdef NDEBUG
#error This program is pointless when NDEBUG disables assert()!
#endif
#define PRIVATE_EXPR_TEST(e, t) BOOST_TEST( ((e), (t)) )
int main()
int
test_main( int , char * [] )
{
using std::cout;
using std::endl;
// Regression test.
Point x;
x = x + Point(3, 4);
x = x - Point(3, 4);
cout << "Created point, and operated on it." << endl;
for (int n = 0; n < 10000; ++n)
{
boost::min_rand r;
boost::minstd_rand r;
tester<long, int>()(r);
tester<long, signed char>()(r);
tester<long, long>()(r);
@@ -367,115 +461,197 @@ int main()
tester<unsigned int, unsigned char>()(r);
}
cout << "Did random tester loop." << endl;
MyInt i1(1);
MyInt i2(2);
MyInt i;
assert( i1.value() == 1 );
assert( i2.value() == 2 );
assert( i.value() == 0 );
BOOST_TEST( i1.value() == 1 );
BOOST_TEST( i2.value() == 2 );
BOOST_TEST( i.value() == 0 );
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 );
cout << "Created MyInt objects.\n";
i = i1 + i2; assert( i.value() == 3 );
i = i + i2; assert( i.value() == 5 );
i = i - i1; assert( i.value() == 4 );
i = i * i2; assert( i.value() == 8 );
i = i / i2; assert( i.value() == 4 );
i = i % (i - i1); assert( i.value() == 1 );
i = i2 + i2; assert( i.value() == 4 );
i = i1 | i2 | i; assert( i.value() == 7 );
i = i & i2; assert( i.value() == 2 );
i = i + i1; assert( i.value() == 3 );
i = i ^ i1; assert( i.value() == 2 );
i = (i+i1)*(i2|i1); assert( i.value() == 9 );
PRIVATE_EXPR_TEST( (i = i2), (i.value() == 2) );
BOOST_TEST( i2 == i );
BOOST_TEST( i1 != i2 );
BOOST_TEST( i1 < i2 );
BOOST_TEST( i1 <= i2 );
BOOST_TEST( i <= i2 );
BOOST_TEST( i2 > i1 );
BOOST_TEST( i2 >= i1 );
BOOST_TEST( i2 >= i );
PRIVATE_EXPR_TEST( (i = i1 + i2), (i.value() == 3) );
PRIVATE_EXPR_TEST( (i = i + i2), (i.value() == 5) );
PRIVATE_EXPR_TEST( (i = i - i1), (i.value() == 4) );
PRIVATE_EXPR_TEST( (i = i * i2), (i.value() == 8) );
PRIVATE_EXPR_TEST( (i = i / i2), (i.value() == 4) );
PRIVATE_EXPR_TEST( (i = i % ( i - i1 )), (i.value() == 1) );
PRIVATE_EXPR_TEST( (i = i2 + i2), (i.value() == 4) );
PRIVATE_EXPR_TEST( (i = i1 | i2 | i), (i.value() == 7) );
PRIVATE_EXPR_TEST( (i = i & i2), (i.value() == 2) );
PRIVATE_EXPR_TEST( (i = i + i1), (i.value() == 3) );
PRIVATE_EXPR_TEST( (i = i ^ i1), (i.value() == 2) );
PRIVATE_EXPR_TEST( (i = ( i + i1 ) * ( i2 | i1 )), (i.value() == 9) );
PRIVATE_EXPR_TEST( (i = i1 << i2), (i.value() == 4) );
PRIVATE_EXPR_TEST( (i = i2 >> i1), (i.value() == 1) );
cout << "Performed tests on MyInt objects.\n";
MyLong j1(1);
MyLong j2(2);
MyLong j;
assert( j1.value() == 1 );
assert( j2.value() == 2 );
assert( j.value() == 0 );
BOOST_TEST( j1.value() == 1 );
BOOST_TEST( j2.value() == 2 );
BOOST_TEST( j.value() == 0 );
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 );
cout << "Created MyLong objects.\n";
assert( (j1 + 2) == 3 );
assert( (1 + j2) == 3 );
j = j1 + j2; assert( j.value() == 3 );
PRIVATE_EXPR_TEST( (j = j2), (j.value() == 2) );
assert( (j + 2) == 5 );
assert( (3 + j2) == 5 );
j = j + j2; assert( j.value() == 5 );
BOOST_TEST( j2 == j );
BOOST_TEST( 2 == j );
BOOST_TEST( j2 == 2 );
BOOST_TEST( j == j2 );
BOOST_TEST( j1 != j2 );
BOOST_TEST( j1 != 2 );
BOOST_TEST( 1 != j2 );
BOOST_TEST( j1 < j2 );
BOOST_TEST( 1 < j2 );
BOOST_TEST( j1 < 2 );
BOOST_TEST( j1 <= j2 );
BOOST_TEST( 1 <= j2 );
BOOST_TEST( j1 <= j );
BOOST_TEST( j <= j2 );
BOOST_TEST( 2 <= j2 );
BOOST_TEST( j <= 2 );
BOOST_TEST( j2 > j1 );
BOOST_TEST( 2 > j1 );
BOOST_TEST( j2 > 1 );
BOOST_TEST( j2 >= j1 );
BOOST_TEST( 2 >= j1 );
BOOST_TEST( j2 >= 1 );
BOOST_TEST( j2 >= j );
BOOST_TEST( 2 >= j );
BOOST_TEST( j2 >= 2 );
BOOST_TEST( (j1 + 2) == 3 );
BOOST_TEST( (1 + j2) == 3 );
PRIVATE_EXPR_TEST( (j = j1 + j2), (j.value() == 3) );
assert( (j - 1) == 4 );
j = j - j1; assert( j.value() == 4 );
BOOST_TEST( (j + 2) == 5 );
BOOST_TEST( (3 + j2) == 5 );
PRIVATE_EXPR_TEST( (j = j + j2), (j.value() == 5) );
assert( (j * 2) == 8 );
assert( (4 * j2) == 8 );
j = j * j2; assert( j.value() == 8 );
BOOST_TEST( (j - 1) == 4 );
PRIVATE_EXPR_TEST( (j = j - j1), (j.value() == 4) );
assert( (j / 2) == 4 );
j = j / j2; assert( j.value() == 4 );
BOOST_TEST( (j * 2) == 8 );
BOOST_TEST( (4 * j2) == 8 );
PRIVATE_EXPR_TEST( (j = j * j2), (j.value() == 8) );
assert( (j % 3) == 1 );
j = j % (j - j1); assert( j.value() == 1 );
BOOST_TEST( (j / 2) == 4 );
PRIVATE_EXPR_TEST( (j = j / j2), (j.value() == 4) );
j = j2 + j2; assert( j.value() == 4 );
BOOST_TEST( (j % 3) == 1 );
PRIVATE_EXPR_TEST( (j = j % ( j - j1 )), (j.value() == 1) );
assert( (1 | j2 | j) == 7 );
assert( (j1 | 2 | j) == 7 );
assert( (j1 | j2 | 4) == 7 );
j = j1 | j2 | j; assert( j.value() == 7 );
PRIVATE_EXPR_TEST( (j = j2 + j2), (j.value() == 4) );
assert( (7 & j2) == 2 );
assert( (j & 2) == 2 );
j = j & j2; assert( j.value() == 2 );
BOOST_TEST( (1 | j2 | j) == 7 );
BOOST_TEST( (j1 | 2 | j) == 7 );
BOOST_TEST( (j1 | j2 | 4) == 7 );
PRIVATE_EXPR_TEST( (j = j1 | j2 | j), (j.value() == 7) );
j = j | j1; assert( j.value() == 3 );
BOOST_TEST( (7 & j2) == 2 );
BOOST_TEST( (j & 2) == 2 );
PRIVATE_EXPR_TEST( (j = j & j2), (j.value() == 2) );
assert( (3 ^ j1) == 2 );
assert( (j ^ 1) == 2 );
j = j ^ j1; assert( j.value() == 2 );
PRIVATE_EXPR_TEST( (j = j | j1), (j.value() == 3) );
j = (j+j1)*(j2|j1); assert( j.value() == 9 );
BOOST_TEST( (3 ^ j1) == 2 );
BOOST_TEST( (j ^ 1) == 2 );
PRIVATE_EXPR_TEST( (j = j ^ j1), (j.value() == 2) );
std::cout << "0 errors detected\n";
return 0;
PRIVATE_EXPR_TEST( (j = ( j + j1 ) * ( j2 | j1 )), (j.value() == 9) );
BOOST_TEST( (j1 << 2) == 4 );
BOOST_TEST( (j2 << 1) == 4 );
PRIVATE_EXPR_TEST( (j = j1 << j2), (j.value() == 4) );
BOOST_TEST( (j >> 2) == 1 );
BOOST_TEST( (j2 >> 1) == 1 );
PRIVATE_EXPR_TEST( (j = j2 >> j1), (j.value() == 1) );
cout << "Performed tests on MyLong objects.\n";
MyChar k1(1);
MyChar k2(2);
MyChar k;
BOOST_TEST( k1.value() == 1 );
BOOST_TEST( k2.value() == 2 );
BOOST_TEST( k.value() == 0 );
cout << "Created MyChar objects.\n";
PRIVATE_EXPR_TEST( (k = k2), (k.value() == 2) );
BOOST_TEST( k2 == k );
BOOST_TEST( k1 != k2 );
BOOST_TEST( k1 < k2 );
BOOST_TEST( k1 <= k2 );
BOOST_TEST( k <= k2 );
BOOST_TEST( k2 > k1 );
BOOST_TEST( k2 >= k1 );
BOOST_TEST( k2 >= k );
cout << "Performed tests on MyChar objects.\n";
MyShort l1(1);
MyShort l2(2);
MyShort l;
BOOST_TEST( l1.value() == 1 );
BOOST_TEST( l2.value() == 2 );
BOOST_TEST( l.value() == 0 );
cout << "Created MyShort objects.\n";
PRIVATE_EXPR_TEST( (l = l2), (l.value() == 2) );
BOOST_TEST( l2 == l );
BOOST_TEST( 2 == l );
BOOST_TEST( l2 == 2 );
BOOST_TEST( l == l2 );
BOOST_TEST( l1 != l2 );
BOOST_TEST( l1 != 2 );
BOOST_TEST( 1 != l2 );
BOOST_TEST( l1 < l2 );
BOOST_TEST( 1 < l2 );
BOOST_TEST( l1 < 2 );
BOOST_TEST( l1 <= l2 );
BOOST_TEST( 1 <= l2 );
BOOST_TEST( l1 <= l );
BOOST_TEST( l <= l2 );
BOOST_TEST( 2 <= l2 );
BOOST_TEST( l <= 2 );
BOOST_TEST( l2 > l1 );
BOOST_TEST( 2 > l1 );
BOOST_TEST( l2 > 1 );
BOOST_TEST( l2 >= l1 );
BOOST_TEST( 2 >= l1 );
BOOST_TEST( l2 >= 1 );
BOOST_TEST( l2 >= l );
BOOST_TEST( 2 >= l );
BOOST_TEST( l2 >= 2 );
cout << "Performed tests on MyShort objects.\n";
return boost::exit_success;
}

View File

@@ -23,7 +23,9 @@
<TT>tie</TT>
</H1>
<P>
<h3>
[tie has been deprecated.&nbsp; Its functionality is supplied by the Boost
Tuples Library.]</h3>
<PRE>
template &lt;class A, class B&gt;
tied&lt;A,B&gt; tie(A&amp; a, B&amp; b);
@@ -124,7 +126,7 @@ The output is:
<TABLE>
<TR valign=top>
<TD nowrap>Copyright &copy 2000</TD><TD>
<A HREF=http://www.boost.org/people/jeremy_siek.htm>Jeremy Siek</A>,
<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>)<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>

View File

@@ -1,75 +0,0 @@
# -*- makefile -*-
DVIPS = dvips
LATEX = pdflatex
LATEXOUT = pdf
RESULT = pdf
#LATEX = latex
#LATEXOUT = dvi
#RESULT = ps
.SUFFIXES: .tex .dvi .ps .pdf .c .lg .eps
.c.lg:
lgrind -i -o $*.lg -a -lc++ $*.c
.eps.pdf:
epstopdf $*.eps
.tex.pdf:
@ if test ! -f $*.ind; then echo "" > $*.ind; fi
@ $(LATEX) $*
@ if ( grep 'Writing index file' $*.log > /dev/null ); \
then makeindex $* ; $(LATEX) $* ; fi
@ if ( grep 'LaTeX Warning: Label(s) may' $*.log > /dev/null ); \
then $(LATEX) $* ; fi
@ if ( grep 'LaTeX Warning: Citation' $*.log > /dev/null ); \
then bibtex $* ; $(LATEX) $* ; fi
@ if ( grep 'LaTeX Warning: Label(s) may' $*.log > /dev/null ); \
then $(LATEX) $* ; fi
@ if ( grep 'LaTeX Warning: Label(s) may' $*.log > /dev/null ); \
then $(LATEX) $* ; fi
@ if ( grep 'LaTeX Warning: Label(s) may' $*.log > /dev/null ); \
then $(LATEX) $* ; fi
.dvi.ps:
$(DVIPS) -o $*.ps $*
.ps.pdf:
distill -v -maxsubsetpct 99 -subsetfonts on -pairs $*.ps $*.pdf
SRCCODE =
#
# Default rule
#
default: iter-adaptor.$(RESULT)
#
# LaTeX stuff
#
TEX = iter-adaptor.tex
iter-adaptor.dvi: $(TEX) $(SRCCODELG)
iter-adaptor.ps: iter-adaptor.dvi
iter-adaptor.pdf: $(PDFPICT) $(TEX) $(SRCCODELG)
dist: iter-adaptor.ps iter-adaptor.pdf
mkdir -p iter-adaptor
cp $(TEX) $(SRCCODELG) $(EPS) $(PS) \
iter-adaptor.bbl iter-adaptor.ps iter-adaptor.pdf \
iter-adaptor
tar cvf - ./iter-adaptor | gzip > iter-adaptor.tar.gz
#
# Standard rules
#
clean:
/bin/rm -f *.dvi *.o *.ps *.pdf *.log *.blg *.bbl *.aux *~ *.out *.ind

View File

@@ -1,36 +0,0 @@
\usepackage{times}
\newif\ifpdf
\ifx\pdfoutput\undefined
\pdffalse
\else
\pdfoutput=1
\pdftrue
\fi
\ifpdf
\usepackage[
pdftex,
colorlinks=true,
linkcolor=blue,filecolor=blue,pagecolor=blue,urlcolor=blue
]{hyperref}
\fi
\ifpdf
\newcommand{\concept}[1]{\hyperref[concept:#1]{\textsf{#1}}}
\newcommand{\stlconcept}[1]{\href{http://www.sgi.com/tech/stl/#1.html}{\textsf{#1}}}
\newcommand{\link}[2]{\hyperref[#1]{#2}}
\else
\newcommand{\concept}[1]{\textsf{#1}}
\newcommand{\stlconcept}[1]{\textsf{#1}}
\newcommand{\href}[2]{#2}
\newcommand{\link}[2]{#2}
\fi
\newcommand{\code}[1]{{\small \texttt{#1}}}
\newcommand{\Note}[1]{\marginpar{\begin{flushleft}%
{%%\tiny %%\footnotesize
{\bf Note:} #1}%
\end{flushleft}}}

File diff suppressed because it is too large Load Diff

View File

@@ -1,102 +0,0 @@
% Paper Formatting according to requirements of Net.Objectdays 2000
\LoadClass[10pt]{article}
\pagestyle{empty}
% ---------------------------------------------------------------------
\textheight193mm
\textwidth122mm
\oddsidemargin44mm
\hoffset-1in \voffset-1in
\topmargin52mm
\headsep0pt
\headheight0pt
% ---------------------------------------------------------------------
\renewcommand\maketitle{\par
\begingroup
\renewcommand\thefootnote{\@fnsymbol\c@footnote}%
\def\@makefnmark{\rlap{\@textsuperscript{\normalfont\@thefnmark}}}%
\long\def\@makefntext##1{\parindent 1em\noindent
\hb@xt@1.8em{%
\hss\@textsuperscript{\normalfont\@thefnmark}}##1}%
\if@twocolumn
\ifnum \col@number=\@ne
\@maketitle
\else
\twocolumn[\@maketitle]%
\fi
\else
\newpage
\global\@topnum\z@ % Prevents figures from going at top of page.
\@maketitle
\fi
\thispagestyle{empty}\@thanks
\endgroup
\setcounter{footnote}{0}%
\global\let\thanks\relax
\global\let\maketitle\relax
\global\let\@maketitle\relax
\global\let\@thanks\@empty
\global\let\@author\@empty
\global\let\@date\@empty
\global\let\@title\@empty
\global\let\title\relax
\global\let\author\relax
\global\let\date\relax
\global\let\and\relax
}
\date{}
\def\@maketitle{%
\newpage
\null
\vskip 2em%
\begin{center}%
\let \footnote \thanks
{\Large \textbf{\@title} \par}%
\vskip 1.5em%
{\large
\lineskip .5em%
{\normalsize
\begin{tabular}[t]{c}%
\@author
\end{tabular}\par}}%
\vskip 1em%
{\large \@date}%
\end{center}%
\par
\vskip 1.5em}
\renewcommand\section{\@startsection {section}{1}{\z@}%
{-3.5ex \@plus -1ex \@minus -.2ex}%
{2.3ex \@plus.2ex}%
{\normalfont\large\bfseries}}
\renewcommand\subsection{\@startsection{subsection}{2}{\z@}%
{-3.25ex\@plus -1ex \@minus -.2ex}%
{1.5ex \@plus .2ex}%
{\normalfont\normalsize\bfseries}}
\renewcommand\subsubsection{\@startsection{subsubsection}{3}{\z@}%
{-3.25ex\@plus -1ex \@minus -.2ex}%
{1.5ex \@plus .2ex}%
{\normalfont\normalsize\bfseries}}
\renewcommand\paragraph{\@startsection{paragraph}{4}{\z@}%
{3.25ex \@plus1ex \@minus.2ex}%
{-1em}%
{\normalfont\normalsize\bfseries}}
\renewcommand\subparagraph{\@startsection{subparagraph}{5}{\parindent}%
{3.25ex \@plus1ex \@minus .2ex}%
{-1em}%
{\normalfont\normalsize\bfseries}}
\renewcommand{\figurename}{Fig}
\renewcommand{\tablename}{Tab}
\long\def\@makecaption#1#2{%
\vskip\abovecaptionskip
\sbox\@tempboxa{{\small\textbf{#1.} #2}}%
\ifdim \wd\@tempboxa >\hsize
{\small\textbf{#1.} #2}\par
\else
\global \@minipagefalse
\hb@xt@\hsize{\hfil\box\@tempboxa\hfil}%
\fi
\vskip\belowcaptionskip}
\renewenvironment{abstract}
{\list{}{\leftmargin1cm\rightmargin\leftmargin}%
\item\relax{\small \textbf{Abstract.}}}
{\endlist}

View File

@@ -1,124 +0,0 @@
@TechReport{stepa.lee-1994:the.s:TR,
author = "A. A. Stepanov and M. Lee",
title = "{The Standard Template Library}",
institution = "ISO Programming Language C++ Project",
year = "1994",
number = "X3J16/94-0095, WG21/N0482",
month = may,
}
@Book{ austern99:_gener_progr_stl,
author = "Matthew H. Austern",
title = "Generic Programming and the {STL}",
publisher = "Addison-Wesley",
year = 1999,
series = "Professional computing series"
}
@Book{koenig97:_rumin_cpp,
author = {Andrew Koenig and Barbara Moo},
title = {Ruminations on {C++}},
publisher = {Addison Wesley},
year = 1997
}
@Book{iso98:_cpp_final_draft_standard,
author = "International Organization for Standardization
(ISO)",
title = "ISO/IEC Final Draft International Standard 14882:
Programming Language C++",
year = 1998,
address = "1 rue de Varemb\'e, Case postale 56, CH-1211
Gen\`eve 20, Switzerland"
}
@Book{alexandrescu01:_modern_cpp_design,
author = {Andrei Alexandrescu},
title = {Modern {C++} Design},
publisher = {Addison Wesley},
year = 2001
}
@BOOK { Barton94,
AUTHOR = "John Barton and Lee Nackman",
TITLE = "Scientific and Engineering {C++}",
PUBLISHER = "Addison-Wesley",
YEAR = 1994
}
@Book{gamma95:_design_patterns,
author = {Erich Gamma and Richard Helm and Ralph Johnson and John Vlissides},
title = {Design Patterns: Elements of Reusable Object-Oriented Software},
publisher = {Addison-Welsey},
year = 1995,
series = {Professional Computing}
}
@Book{stroustrup00:_cpp_prog_lang,
author = {Bjarne Stroustrup},
title = {The {C++} Programming Language},
publisher = {Addison-Wesley},
year = 2000,
edition = {Special}
}
@Article{alexandrescu98:_compound_iters,
author = {Andrei Alexandrescu},
title = {Compound iterators of {STL}},
journal = {{C/C++} Users Journal},
year = 1998,
volume = 16,
number = 10,
pages = {79-82},
month = October
}
@Article{becker98:_smart_iteraters,
author = {Thomas Becker},
title = {Smart Iterators and STL},
journal = {{C/C++} Users Journal},
year = 1998,
volume = 16,
number = 9,
month = {September}
}
@InBook{siek99:_scitools,
author = {Jeremy G. Siek and Andrew Lumsdaine},
title = {Modern Software Tools for Scientific Computing},
chapter = {A Modern Framework for Portable High Performance
Numerical Linear Algebra},
publisher = {Birkhauser},
year = 1999,
}
@TechReport{siek01:_improved_iter_cat,
author = {Jeremy Siek},
title = {Improved Iterator Categories and Requirements},
institution = {ISO IEC JTC1/SC22/WG21 - C++},
year = 2001,
number = {N1297}
}
@Book{mehlhorn99:_leda,
author = {K. Mehlhorn and St. N\"aher},
title = {The LEDA Platform of Combinatorial and Geometric Computing},
publisher = {Cambridge University Press},
year = 1999
}
@Book{ knu94:sgb,
author = {D. E. Knuth},
title = {Stanford GraphBase: a platform for combinatorial computing},
publisher = {ACM Press},
year = {1994}
}
@Misc{czarnecki00:_named_param,
author = {Krzysztof Czarnecki and Ulrich Eisenecker},
title = {Named Parameters for Configuration Generators},
howpublished = {http://www.generative-programming.org/namedparams/},
year = 2000
}

View File

@@ -1,249 +0,0 @@
@InProceedings{TMPW00:Eisenecker,
AUTHOR = "Ulrich W. Eisenecker and Frank Blinn and Krzysztof Czarnecki",
TITLE = "A Solution to the Constructor-Problem of Mixin-Based Programming in {C++}",
BOOKTITLE = "First Workshop on {C++} Template Programming,
Erfurt, Germany",
MONTH = "October 10",
YEAR = "2000",
URL = "http://oonumerics.org/tmpw00/",
ABSTRACT =
"Mixin-Based Programming in C++ is a powerful programming style
based on the parameterized inheritance idiom and the composition
of C++ templates. Type expressions describing specific inheritance
hierarchies can be composed either automatically using generative
programming idioms in C++ or manually. Unfortunately, the mixin-based
C++ programming techniques published to date do not adequately support
optional and alternative mixin classes with constructors expecting
varying numbers of arguments, which are common in practice. This
is because the varying base class constructors do not provide a
uniform interface on which the constructors of the derived classes
could rely. This paper discusses several partial solutions to this
problem that were proposed to date and presents a new, complete
solution. The new solution uses generative programming techniques to
automatically generate the appropriate constructors, and this way it
avoids the overhead and clumsiness of instantiating composed mixin
classes in the client code using the partial solutions. In fact,
the new solution allows users to instantiate automatically composed
mixin classes with the simplicity of instantiating concrete classes
from traditional class hierarchies. Finally, the new solution does
not suffer from the scalability problems of the partial solutions."
}
@InProceedings{TMPW00:Berti,
AUTHOR = "Guntram Berti",
TITLE = "Generic Components for Grid Data Structures and Algorithms with {C++}",
BOOKTITLE = "First Workshop on {C++} Template Programming,
Erfurt, Germany",
MONTH = "October 10",
YEAR = "2000",
URL = "http://oonumerics.org/tmpw00/",
ABSTRACT =
"Grids are fundamental data structures for representing
geometric structures or their subdivisions. We propose a strategy
for decoupling algorithms working on grids from the details of
grid representations, using a generic programming approach in C++.
Functionality of grid data structures is captured by a small set of
primitives, divided into combinatorial and geometric ones. Special
attention is paid to the generic implementation of grid functions, which
correspond to the notion of mappings from grid elements (e. g. vertices)
to entities of a given type. Experiments indicate that the overhead
of the generic formulation is low and can be completely eliminated in
some cases."
}
@InProceedings{TMPW00:Veldhuizen,
AUTHOR = "Todd L. Veldhuizen",
TITLE = "Five compilation models for {C++} templates",
BOOKTITLE = "First Workshop on {C++} Template Programming,
Erfurt, Germany",
MONTH = "October 10",
YEAR = "2000",
URL = "http://oonumerics.org/tmpw00/",
ABSTRACT =
"This paper proposes an alternate structure for C++ compilers.
Type analysis is removed from the compiler and replaced with a
`type system library' which is treated as source code by the
compiler. Type computations are embedded in the intermediate
language of the compiler, and partial evaluation is used to drive
type analysis and template instantiation. By making simple changes to
the behavior of the partial evaluator, a wide range of compilation
models is achieved, each with a distinct tradeoff of compile time, code
size, and code speed. These models range from pure dynamic typing --
ideal for scripting C++ -- to profile-directed template instantiation.
This approach may solve several serious problems in compiling C++:
it achieves separate compilation of templates, allows template
code to be distributed in binary form by deferring template instantiation
until run time, and reduces the code bloat associated with
templates."
}
@InProceedings{TMPW00:Baus,
AUTHOR = "Christopher Baus and Thomas Becker",
TITLE = "Custom Iterators for the {STL}",
BOOKTITLE = "First Workshop on {C++} Template Programming,
Erfurt, Germany",
MONTH = "October 10",
YEAR = "2000",
URL = "http://oonumerics.org/tmpw00/",
ABSTRACT =
"We discuss several kinds of custom iterators for use with the STL
that are substantially different from the iterators that come with
the STL. We present class templates that implement these custom
iterators in a generic manner."
}
@InProceedings{TMPW00:Weiser,
AUTHOR = "Martin Weiser and Gary Powell",
TITLE = "The {View Template Library}",
BOOKTITLE = "First Workshop on {C++} Template Programming,
Erfurt, Germany",
MONTH = "October 10",
YEAR = "2000",
URL = "http://oonumerics.org/tmpw00/",
ABSTRACT =
"Views are container adaptors providing access to different
on the fly generated representations of the data in the container they
are applied to. The concept fits nicely into the framework defined by
the STL. This paper explains design, usage, and implementation of the
View Template Library, the currently most advanced implementation of
the views concept."
}
@InProceedings{TMPW00:Striegnitz,
AUTHOR = "J{\"o}rg Striegnitz and Stephen A. Smith",
TITLE = "An Expression Template aware Lambda Function",
BOOKTITLE = "First Workshop on {C++} Template Programming,
Erfurt, Germany",
MONTH = "October 10",
YEAR = "2000",
URL = "http://oonumerics.org/tmpw00/",
ABSTRACT =
"Template libraries such as the STL contain several generic algorithms
that expect functions as arguments and thereby cause frequent use of
function objects. User-defined function objects are awkward because
they must be declared as a class in namespace scope before they may
be used. In this paper, we describe a lambda function for C++, which
allows users to define function objects on the fly, without writing class
declarations. We show that, by using expression templates, the lambda
function can be implemented without hurting the runtime performance of a
program. Expression templates can also help to overcome the performance
penalties that may arise when using expressions over user-defined
types. Thus, we based our approach on PETE which is a framework
that simplifies the addition of expression template functionality to
user-defined classes."
}
@InProceedings{TMPW00:McNamara,
AUTHOR = "Brian McNamara and Yannis Smaragdakis",
TITLE = "Static Interfaces in {C++}",
BOOKTITLE = "First Workshop on {C++} Template Programming,
Erfurt, Germany",
MONTH = "October 10",
YEAR = "2000",
URL = "http://oonumerics.org/tmpw00/",
ABSTRACT =
"We present an extensible framework for defining and
using ``static interfaces'' in C++. Static interfaces are especially
useful as constraints on template parameters. That is, in addition to the
usual template $class T$, template definitions can specify that T ``isa''
Foo, for some static interface named Foo. These ``isa-constraints'' can be
based on either inheritance (named conformance: T publicly inherits Foo),
members (structural conformance: T has these member functions with these
signatures), or both. The constraint mechanism imposes no space or time
overheads at runtime; virtual functions are conspicuously absent from
our framework.
We demonstrate two key utilities of static interfaces. First,
constraints enable better error messages with template code. By applying
static interfaces as constraints, instantiating a template with the
wrong type is an error that can be caught at the instantiation point,
rather than later (typically in the bowels of the implementation).
Authors of template classes and template functions can also dispatch
``custom error messages'' to report named constraint violations by
clients, making debugging easier. We show examples of the improvement of
error messages when constraints are applied to STL code.
Second, constraints enable automatic compile-time dispatch of different
implementations of class or function templates based on the named
conformance properties of the template types. For example, $Set<T>$ can be
written to automatically choose the most efficient implementation: use a
hashtable implementation if ``T isa Hashable'', or else a binary search
tree if ``T isa LessThanComparable'' , or else a linked-list if merely ``T
isa EqualityComparable''. This dispatch can be completely hidden from
clients of Set, who just use $Set<T>$ as usual."
}
@InProceedings{TMPW00:Siek,
AUTHOR = "Jeremy Siek and Andrew Lumsdaine",
TITLE = "Concept Checking: Binding Parametric Polymorphism in {C++}",
BOOKTITLE = "First Workshop on {C++} Template Programming,
Erfurt, Germany",
MONTH = "October 10",
YEAR = "2000",
URL = "http://oonumerics.org/tmpw00/",
ABSTRACT =
"Generic programming in C++ is characterized by the use of template
parameters to represent abstract data types (or ``concepts'').
However, the C++ language itself does not provide a mechanism for
explicitly handling concepts. As a result, it can be difficult to
insure that a concrete type meets the requirements of the concept it
is supposed to represent. Error messages resulting from incorrect
use of a concrete type can be particularly difficult to decipher.
In this paper we present techniques to check parameters in generic
C++ libraries. Our techniques use standard C++ and introduce no
run-time overhead."
}
@InProceedings{TMPW00:Kuehl,
AUTHOR = "Dietmar K{\"u}hl",
TITLE = "{STL} and {OO} Don't Easily Mix",
BOOKTITLE = "First Workshop on {C++} Template Programming,
Erfurt, Germany",
MONTH = "October 10",
YEAR = "2000",
URL = "http://oonumerics.org/tmpw00/",
ABSTRACT =
"The STL is a powerful tool for many kinds of processing. Unfortunately,
using polymorphic objects with the STL seems not to work: Polymorphic
objects stored in STL containers either get sliced (i.e. only the base
part is copied or assigned but not the derived part) or, when storing
pointers to them instead, are not destroyed. Applying algorithms to
such containers often results in the wrong thing or complex predicate
objects are needed. This article shows how to overcome at least some
of these problems using some adaptors and also outlines a possible
implementation of STL for better integration with polymorphic objects.
The improved integration just acknowledges the distinction between the
object and the entity used to maintain it."
}
@InProceedings{TMPW00:Eichelberger,
AUTHOR = "H. Eichelberger and J. Wolff v. Gudenberg",
TITLE = "{UML} Description of the {STL}",
BOOKTITLE = "First Workshop on {C++} Template Programming,
Erfurt, Germany",
MONTH = "October 10",
YEAR = "2000",
URL = "http://oonumerics.org/tmpw00/eichelberger.pdf",
ABSTRACT =
"In this paper we show how the specification of the
Standard Template Library STL and its implementation can be described
by UML diagrams. We define appropriate stereotypes to
describe STL concepts like containers, iterators, function
objects and global algorithms. For the graphical description of the
implementation of the STL we extend the UML metamodel."
}