mirror of
https://github.com/boostorg/utility.git
synced 2025-10-05 21:40:59 +02:00
Compare commits
1 Commits
boost-1.18
...
svn-branch
Author | SHA1 | Date | |
---|---|---|---|
|
11fa077264 |
116
Assignable.html
116
Assignable.html
@@ -1,116 +0,0 @@
|
||||
<HTML>
|
||||
<!--
|
||||
-- Copyright (c) Jeremy Siek 2000
|
||||
--
|
||||
-- Permission to use, copy, modify, distribute and sell this software
|
||||
-- and its documentation for any purpose is hereby granted without fee,
|
||||
-- provided that the above copyright notice appears in all copies and
|
||||
-- that both that copyright notice and this permission notice appear
|
||||
-- in supporting documentation. Silicon Graphics makes no
|
||||
-- representations about the suitability of this software for any
|
||||
-- purpose. It is provided "as is" without express or implied warranty.
|
||||
-->
|
||||
<Head>
|
||||
<Title>Assignable</Title>
|
||||
</HEAD>
|
||||
<BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"
|
||||
ALINK="#ff0000">
|
||||
<IMG SRC="../../c++boost.gif"
|
||||
ALT="C++ Boost" width="277" height="86">
|
||||
<!--end header-->
|
||||
<BR Clear>
|
||||
<H1>Assignable</H1>
|
||||
|
||||
<h3>Description</h3>
|
||||
A type is Assignable if it is possible to assign one object of the type
|
||||
to another object of that type.
|
||||
|
||||
|
||||
<h3>Notation</h3>
|
||||
<Table>
|
||||
<TR>
|
||||
<TD VAlign=top>
|
||||
<tt>T</tt>
|
||||
</TD>
|
||||
<TD VAlign=top>
|
||||
is type that is a model of Assignable
|
||||
</TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD VAlign=top>
|
||||
<tt>t</tt>
|
||||
</TD>
|
||||
<TD VAlign=top>
|
||||
is an object of type <tt>T</tt>
|
||||
</TD>
|
||||
</tr>
|
||||
|
||||
<TR>
|
||||
<TD VAlign=top>
|
||||
<tt>u</tt>
|
||||
</TD>
|
||||
<TD VAlign=top>
|
||||
is an object of type <tt>T</tt> or possibly <tt>const T</tt>
|
||||
</TD>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
<h3>Definitions</h3>
|
||||
<h3>Valid expressions</h3>
|
||||
<Table border>
|
||||
<TR>
|
||||
<TH>
|
||||
Name
|
||||
</TH>
|
||||
<TH>
|
||||
Expression
|
||||
</TH>
|
||||
<TH>
|
||||
Return type
|
||||
</TH>
|
||||
<TH>
|
||||
Semantics
|
||||
</TH>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD VAlign=top>
|
||||
Assignment
|
||||
</TD>
|
||||
<TD VAlign=top>
|
||||
<tt>t = u</tt>
|
||||
</TD>
|
||||
<TD VAlign=top>
|
||||
<tt>T&</tt>
|
||||
</TD>
|
||||
<TD VAlign=top>
|
||||
<tt>t</tt> is equivalent to <tt>u</tt>
|
||||
</TD>
|
||||
</TR>
|
||||
|
||||
</table>
|
||||
|
||||
|
||||
</table>
|
||||
<h3>Models</h3>
|
||||
|
||||
<UL>
|
||||
<LI><tt>int</tt>
|
||||
<LI><tt>std::pair</tt>
|
||||
</UL>
|
||||
|
||||
<h3>See also</h3>
|
||||
<a href="http://www.sgi.com/Technology/STL/DefaultConstructible.html">DefaultConstructible</A>
|
||||
and
|
||||
<A href="./CopyConstructible.html">CopyConstructible</A>
|
||||
|
||||
<br>
|
||||
<HR>
|
||||
<TABLE>
|
||||
<TR valign=top>
|
||||
<TD nowrap>Copyright © 2000</TD><TD>
|
||||
<A HREF=http://www.lsc.nd.edu/~jsiek>Jeremy Siek</A>, Univ.of Notre Dame (<A HREF="mailto:jsiek@lsc.nd.edu">jsiek@lsc.nd.edu</A>)
|
||||
</TD></TR></TABLE>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
@@ -16,7 +16,7 @@
|
||||
<BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"
|
||||
ALINK="#ff0000">
|
||||
<IMG SRC="../../c++boost.gif"
|
||||
ALT="C++ Boost" width="277" height="86">
|
||||
ALT="C++ Boost">
|
||||
<!--end header-->
|
||||
<BR Clear>
|
||||
<H1>CopyConstructible</H1>
|
||||
|
@@ -15,7 +15,7 @@
|
||||
<BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"
|
||||
ALINK="#ff0000">
|
||||
<IMG SRC="../../c++boost.gif"
|
||||
ALT="C++ Boost" width="277" height="86">
|
||||
ALT="C++ Boost">
|
||||
|
||||
<BR Clear>
|
||||
|
||||
|
@@ -196,7 +196,7 @@ struct filler<true>
|
||||
template <typename I, typename T>
|
||||
static void do_fill(I first, I last, T val)
|
||||
{
|
||||
std::memset(first, val, last-first);
|
||||
memset(first, val, last-first);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -421,4 +421,3 @@ int main()
|
||||
|
||||
|
||||
|
||||
|
||||
|
@@ -27,16 +27,10 @@ never occur, and that parameters are passed in the most efficient
|
||||
manner possible (see <a href="#examples">examples</a>). In each
|
||||
case if your existing practice is to use the type defined on the
|
||||
left, then replace it with the call_traits defined type on the
|
||||
right. </p>
|
||||
|
||||
<p>Note that for compilers that do not support either partial
|
||||
specialization or member templates, no benefit will occur from
|
||||
using call_traits: the call_traits defined types will always be
|
||||
the same as the existing practice in this case. In addition if
|
||||
only member templates and not partial template specialisation is
|
||||
support by the compiler (for example Visual C++ 6) then call_traits
|
||||
can not be used with array types (although it can be used to
|
||||
solve the reference to reference problem).</p>
|
||||
right. Note that for compilers that do not support partial
|
||||
specialization, no benefit will occur from using call_traits: the
|
||||
call_traits defined types will always be the same as the existing
|
||||
practice in this case.</p>
|
||||
|
||||
<table border="0" cellpadding="7" cellspacing="1" width="797">
|
||||
<tr>
|
||||
@@ -575,9 +569,7 @@ std::pair<
|
||||
degraded to pointers if the deduced types are arrays, similar
|
||||
situations occur in the standard binders and adapters: in
|
||||
principle in any function that "wraps" a temporary
|
||||
whose type is deduced. Note that the function arguments to make_pair
|
||||
are not expressed in terms of call_traits: doing so would prevent
|
||||
template argument deduction from functioning.</p>
|
||||
whose type is deduced.</p>
|
||||
|
||||
<h4><a name="ex4"></a>Example 4 (optimising fill):</h4>
|
||||
|
||||
@@ -640,14 +632,6 @@ Exactly how much mileage you will get from this depends upon your
|
||||
compiler - we could really use some accurate benchmarking
|
||||
software as part of boost for cases like this.</p>
|
||||
|
||||
<p>Note that the function arguments to fill are not expressed in
|
||||
terms of call_traits: doing so would prevent template argument
|
||||
deduction from functioning. Instead fill acts as a "thin
|
||||
wrapper" that is there to perform template argument
|
||||
deduction, the compiler will optimise away the call to fill all
|
||||
together, replacing it with the call to filler<>::do_fill,
|
||||
which does use call_traits.</p>
|
||||
|
||||
<h3>Rationale</h3>
|
||||
|
||||
<p>The following notes are intended to briefly describe the
|
||||
@@ -729,7 +713,7 @@ specialisation).</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<p>Revised 01 September 2000</p>
|
||||
<p>Revised 18 June 2000</p>
|
||||
|
||||
<p><EFBFBD> Copyright boost.org 2000. Permission to copy, use, modify,
|
||||
sell and distribute this document is granted provided this
|
||||
|
@@ -6,8 +6,6 @@
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
// standalone test program for <boost/call_traits.hpp>
|
||||
// 03 Oct 2000:
|
||||
// Enabled extra tests for VC6.
|
||||
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
@@ -118,7 +116,7 @@ void checker<T>::operator()(param_type p)
|
||||
assert(t == c.get());
|
||||
assert(t == c.const_get());
|
||||
|
||||
//cout << "typeof contained<" << typeid(T).name() << ">::v_ is: " << typeid(&contained<T>::v_).name() << endl;
|
||||
cout << "typeof contained<" << typeid(T).name() << ">::v_ is: " << typeid(&contained<T>::v_).name() << endl;
|
||||
cout << "typeof contained<" << typeid(T).name() << ">::value() is: " << typeid(&contained<T>::value).name() << endl;
|
||||
cout << "typeof contained<" << typeid(T).name() << ">::get() is: " << typeid(&contained<T>::get).name() << endl;
|
||||
cout << "typeof contained<" << typeid(T).name() << ">::const_get() is: " << typeid(&contained<T>::const_get).name() << endl;
|
||||
@@ -192,18 +190,17 @@ int main()
|
||||
int i = 2;
|
||||
c2(i);
|
||||
int* pi = &i;
|
||||
#if defined(BOOST_MSVC6_MEMBER_TEMPLATES) || !defined(BOOST_NO_MEMBER_TEMPLATES)
|
||||
checker<int*> c3;
|
||||
c3(pi);
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
checker<int&> c4;
|
||||
c4(i);
|
||||
checker<const int&> c5;
|
||||
c5(i);
|
||||
#if !defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
|
||||
int a[2] = {1,2};
|
||||
checker<int[2]> c6;
|
||||
c6(a);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
check_wrap(wrap(2), 2);
|
||||
@@ -232,7 +229,7 @@ int main()
|
||||
type_test(int*&, boost::call_traits<int*>::reference)
|
||||
type_test(int*const&, boost::call_traits<int*>::const_reference)
|
||||
type_test(int*const, boost::call_traits<int*>::param_type)
|
||||
#if defined(BOOST_MSVC6_MEMBER_TEMPLATES) || !defined(BOOST_NO_MEMBER_TEMPLATES)
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
type_test(int&, boost::call_traits<int&>::value_type)
|
||||
type_test(int&, boost::call_traits<int&>::reference)
|
||||
type_test(const int&, boost::call_traits<int&>::const_reference)
|
||||
@@ -251,7 +248,6 @@ int main()
|
||||
type_test(const int&, boost::call_traits<const int&>::reference)
|
||||
type_test(const int&, boost::call_traits<const int&>::const_reference)
|
||||
type_test(const int&, boost::call_traits<const int&>::param_type)
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
type_test(const int*, boost::call_traits<int[3]>::value_type)
|
||||
type_test(int(&)[3], boost::call_traits<int[3]>::reference)
|
||||
type_test(const int(&)[3], boost::call_traits<int[3]>::const_reference)
|
||||
@@ -260,11 +256,6 @@ int main()
|
||||
type_test(const int(&)[3], boost::call_traits<const int[3]>::reference)
|
||||
type_test(const int(&)[3], boost::call_traits<const int[3]>::const_reference)
|
||||
type_test(const int*const, boost::call_traits<const int[3]>::param_type)
|
||||
#else
|
||||
std::cout << "You're compiler does not support partial template instantiation, skipping 8 tests (8 errors)" << std::endl;
|
||||
failures += 8;
|
||||
test_count += 8;
|
||||
#endif
|
||||
#else
|
||||
std::cout << "You're compiler does not support partial template instantiation, skipping 20 tests (20 errors)" << std::endl;
|
||||
failures += 20;
|
||||
@@ -327,7 +318,7 @@ struct call_traits_test<T, true>
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
void call_traits_test<T, true>::assert_construct(typename boost::call_traits<T>::param_type val)
|
||||
void call_traits_test<T, true>::assert_construct(boost::call_traits<T>::param_type val)
|
||||
{
|
||||
//
|
||||
// this is to check that the call_traits assertions are valid:
|
||||
@@ -356,11 +347,9 @@ void call_traits_test<T, true>::assert_construct(typename boost::call_traits<T>:
|
||||
template struct call_traits_test<int>;
|
||||
template struct call_traits_test<const int>;
|
||||
template struct call_traits_test<int*>;
|
||||
#if defined(BOOST_MSVC6_MEMBER_TEMPLATES) || !defined(BOOST_NO_MEMBER_TEMPLATES)
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template struct call_traits_test<int&>;
|
||||
template struct call_traits_test<const int&>;
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template struct call_traits_test<int[2], true>;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@@ -110,10 +110,6 @@ int main( int argc, char * argv[] )
|
||||
c = numeric_cast<signed char>( small_negative_value );
|
||||
assert( c == -1 );
|
||||
|
||||
// These tests courtesy of Joe R NWP Swatosh<joe.r.swatosh@usace.army.mil>
|
||||
assert( 0.0f == numeric_cast<float>( 0.0 ) );
|
||||
assert( 0.0 == numeric_cast<double>( 0.0 ) );
|
||||
|
||||
// tests which should result in errors being detected
|
||||
|
||||
caught_exception = false;
|
||||
|
@@ -6,8 +6,6 @@
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
// standalone test program for <boost/compressed_pair.hpp>
|
||||
// Revised 03 Oct 2000:
|
||||
// Enabled tests for VC6.
|
||||
|
||||
#include <iostream>
|
||||
#include <typeinfo>
|
||||
@@ -41,23 +39,6 @@ template <> struct is_POD<empty_POD_UDT>
|
||||
#endif
|
||||
}
|
||||
|
||||
struct non_empty1
|
||||
{
|
||||
int i;
|
||||
non_empty1() : i(1){}
|
||||
non_empty1(int v) : i(v){}
|
||||
friend bool operator==(const non_empty1& a, const non_empty1& b)
|
||||
{ return a.i == b.i; }
|
||||
};
|
||||
|
||||
struct non_empty2
|
||||
{
|
||||
int i;
|
||||
non_empty2() : i(3){}
|
||||
non_empty2(int v) : i(v){}
|
||||
friend bool operator==(const non_empty2& a, const non_empty2& b)
|
||||
{ return a.i == b.i; }
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
@@ -72,22 +53,15 @@ int main()
|
||||
assert(cp1b.second() == 1.3);
|
||||
assert(cp1.first() == 2);
|
||||
assert(cp1.second() == 2.3);
|
||||
compressed_pair<non_empty1, non_empty2> cp1c(non_empty1(9));
|
||||
assert(cp1c.second() == non_empty2());
|
||||
assert(cp1c.first() == non_empty1(9));
|
||||
compressed_pair<non_empty1, non_empty2> cp1d(non_empty2(9));
|
||||
assert(cp1d.second() == non_empty2(9));
|
||||
assert(cp1d.first() == non_empty1());
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
compressed_pair<empty_UDT, int> cp2(2);
|
||||
assert(cp2.second() == 2);
|
||||
#endif
|
||||
compressed_pair<int, empty_UDT> cp3(1);
|
||||
assert(cp3.first() ==1);
|
||||
compressed_pair<empty_UDT, empty_UDT> cp4;
|
||||
compressed_pair<empty_UDT, empty_POD_UDT> cp5;
|
||||
compressed_pair<int, empty_UDT> cp9(empty_UDT());
|
||||
compressed_pair<int, empty_UDT> cp10(1);
|
||||
assert(cp10.first() == 1);
|
||||
#if defined(BOOST_MSVC6_MEMBER_TEMPLATES) || !defined(BOOST_NO_MEMBER_TEMPLATES) || !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
int i = 0;
|
||||
compressed_pair<int&, int&> cp6(i,i);
|
||||
assert(cp6.first() == i);
|
||||
@@ -128,25 +102,21 @@ template class boost::compressed_pair<empty_UDT, empty_POD_UDT>;
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
#ifndef __MWERKS__
|
||||
//
|
||||
// now some for which only a few specific members can be instantiated,
|
||||
// first references:
|
||||
template double& compressed_pair<double, int&>::first();
|
||||
template int& compressed_pair<double, int&>::second();
|
||||
#if !(defined(__GNUC__) && (__GNUC__ == 2) && (__GNUC_MINOR__ < 95))
|
||||
template compressed_pair<double, int&>::compressed_pair(int&);
|
||||
#endif
|
||||
template compressed_pair<double, int&>::compressed_pair(call_traits<double>::param_type,int&);
|
||||
//
|
||||
// and then arrays:
|
||||
#ifndef __MWERKS__
|
||||
#ifndef __BORLANDC__
|
||||
template call_traits<int[2]>::reference compressed_pair<double, int[2]>::second();
|
||||
#endif
|
||||
template call_traits<double>::reference compressed_pair<double, int[2]>::first();
|
||||
#if !(defined(__GNUC__) && (__GNUC__ == 2) && (__GNUC_MINOR__ < 95))
|
||||
template compressed_pair<double, int[2]>::compressed_pair(call_traits<double>::param_type);
|
||||
#endif
|
||||
template compressed_pair<double, int[2]>::compressed_pair(const double&);
|
||||
template compressed_pair<double, int[2]>::compressed_pair();
|
||||
#endif // __MWERKS__
|
||||
#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
@@ -154,3 +124,4 @@ template compressed_pair<double, int[2]>::compressed_pair();
|
||||
|
||||
|
||||
|
||||
|
||||
|
@@ -75,9 +75,7 @@ namespace details
|
||||
template <typename T>
|
||||
inline void cp_swap(T& t1, T& t2)
|
||||
{
|
||||
#ifndef __GNUC__
|
||||
using std::swap;
|
||||
#endif
|
||||
swap(t1, t2);
|
||||
}
|
||||
|
||||
|
@@ -9,14 +9,6 @@
|
||||
// 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
|
||||
|
||||
@@ -30,85 +22,6 @@
|
||||
|
||||
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
|
||||
{
|
||||
@@ -118,8 +31,6 @@ struct call_traits
|
||||
typedef const T& param_type;
|
||||
};
|
||||
|
||||
#endif // member templates
|
||||
|
||||
}
|
||||
|
||||
#endif // BOOST_OB_CALL_TRAITS_HPP
|
||||
|
@@ -8,10 +8,6 @@
|
||||
// see libs/utility/compressed_pair.hpp
|
||||
//
|
||||
/* Release notes:
|
||||
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:
|
||||
@@ -33,376 +29,6 @@
|
||||
|
||||
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:
|
||||
//
|
||||
namespace detail{
|
||||
|
||||
template <class A, class T1, class T2>
|
||||
struct best_convertion_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_convertion_traits<A, T1, T2>::value>::init(val, &_first, &_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_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_convertion_traits<A, T1, T2>::value>::init(val, &_first, static_cast<T2*>(this));
|
||||
}
|
||||
|
||||
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_convertion_traits<A, T1, T2>::value>::init(val, static_cast<T1*>(this), &_second);
|
||||
}
|
||||
|
||||
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_convertion_traits<A, T1, T2>::value>::init(val, static_cast<T1*>(this), static_cast<T2*>(this));
|
||||
}
|
||||
|
||||
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) {}
|
||||
|
||||
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() {}
|
||||
|
||||
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
|
||||
@@ -446,10 +72,7 @@ inline void swap(compressed_pair<T1, T2>& x, compressed_pair<T1, T2>& y)
|
||||
x.swap(y);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // boost
|
||||
|
||||
#endif // BOOST_OB_COMPRESSED_PAIR_HPP
|
||||
|
||||
|
||||
|
@@ -69,10 +69,6 @@
|
||||
#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 {
|
||||
|
||||
|
72
index.htm
Normal file
72
index.htm
Normal file
@@ -0,0 +1,72 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
||||
<meta name="GENERATOR" content="Microsoft FrontPage 4.0">
|
||||
<meta name="ProgId" content="FrontPage.Editor.Document">
|
||||
<title>Boost Utility Library</title>
|
||||
</head>
|
||||
|
||||
<body bgcolor="#FFFFFF" text="#000000">
|
||||
|
||||
<table border="1" cellpadding="2" bgcolor="#007F7F">
|
||||
<tr>
|
||||
<td bgcolor="#FFFFFF"><img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" width="277" height="86"></td>
|
||||
<td><a href="../../index.htm"><font color="#FFFFFF" size="4" face="Arial">Home</font></a></td>
|
||||
<td><a href="../../libraries.htm"><font color="#FFFFFF" size="4" face="Arial">Libraries</font></a></td>
|
||||
<td><a href="../../people.htm"><font color="#FFFFFF" size="4" face="Arial">People</font></a></td>
|
||||
<td><a href="../../more/faq.htm"><font color="#FFFFFF" size="4" face="Arial">FAQ</font></a></td>
|
||||
<td><a href="../../more/index.htm"><font color="#FFFFFF" size="4" face="Arial">More</font></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<h1>Boost Utility Library</h1>
|
||||
<table border="1" cellpadding="5">
|
||||
<tr>
|
||||
<td><b><i>Header</i></b></td>
|
||||
<td><b><i>Contents</i></b></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="../../boost/utility.hpp"><code>boost/utility.hpp<br>
|
||||
</code></a><a href="utility.htm">[Documentation]</a></td>
|
||||
<td>Class <b>noncopyable</b> plus <b>next()</b> and <b>prior()</b> template
|
||||
functions.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="../../boost/cast.hpp"><code>boost/cast.hpp</code></a><br>
|
||||
<a href="cast.htm">[Documentation]</a></td>
|
||||
<td><b>polymorphic_cast</b>, <b>implicit_cast</b>, and <b>numeric_cast</b>
|
||||
function templates.
|
||||
<p><i>[Beta.]</i></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="../../boost/operators.hpp">boost/operators.hpp</a><br>
|
||||
<a href="operators.htm">[Documentation]</a></td>
|
||||
<td>Templates <b>equality_comparable</b>, <b>less_than_comparable</b>, <b>addable</b>,
|
||||
and the like ease the task of defining comparison and arithmetic
|
||||
operators, and iterators.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="../../boost/detail/type_traits.hpp">boost/type_traits.hpp</a><br>
|
||||
[<a href="type_traits.htm">Documentation</a>]</td>
|
||||
<td>Template classes that describe the fundamental properties of a type. [<a href="c++_type_traits.htm">DDJ
|
||||
Article "C++ type traits"</a>]</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="../../boost/detail/call_traits.hpp">boost/call_traits.hpp</a><br>
|
||||
[<a href="call_traits.htm">Documentation</a>]</td>
|
||||
<td>Template class call_traits<T>, that defines types used for passing
|
||||
parameters to and from a proceedure.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="../../boost/detail/compressed_pair.hpp">boost/compressed_pair.hpp</a><br>
|
||||
[<a href="compressed_pair.htm">Documentation</a>]</td>
|
||||
<td>Template class compressed_pait<T1, T2> which pairs two values
|
||||
using the empty member optimisation where appropriate.</td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %B %Y" startspan -->27 July 2000<!--webbot bot="Timestamp" endspan i-checksum="18770" --></p>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
@@ -1,144 +0,0 @@
|
||||
// Demonstrate and test boost/operators.hpp on std::iterators -------------//
|
||||
|
||||
// (C) Copyright Jeremy Siek 1999. Permission to copy, use, modify,
|
||||
// sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
|
||||
// See http://www.boost.org for most recent version including documentation.
|
||||
|
||||
// Revision History
|
||||
// 13 Jun 00 Added const version of the iterator tests (Jeremy Siek)
|
||||
// 12 Dec 99 Initial version with iterator operators (Jeremy Siek)
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <boost/pending/iterator_adaptors.hpp>
|
||||
#include <boost/pending/iterator_tests.hpp>
|
||||
#include <boost/pending/integer_range.hpp>
|
||||
|
||||
struct my_iterator_tag : public std::random_access_iterator_tag { };
|
||||
|
||||
|
||||
using boost::dummyT;
|
||||
|
||||
struct my_iter_traits {
|
||||
typedef dummyT value_type;
|
||||
typedef dummyT* pointer;
|
||||
typedef dummyT& reference;
|
||||
typedef my_iterator_tag iterator_category;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
};
|
||||
|
||||
struct my_const_iter_traits {
|
||||
typedef dummyT value_type;
|
||||
typedef const dummyT* pointer;
|
||||
typedef const dummyT& reference;
|
||||
typedef my_iterator_tag iterator_category;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
};
|
||||
|
||||
typedef boost::iterator_adaptors
|
||||
<dummyT*, const dummyT*,
|
||||
my_iter_traits, my_const_iter_traits> My;
|
||||
|
||||
struct mult_functor {
|
||||
typedef int result_type;
|
||||
typedef int argument_type;
|
||||
// Functors used with transform_iterator must be
|
||||
// DefaultConstructible, as the transform_iterator must be
|
||||
// DefaultConstructible to satisfy the requirements for
|
||||
// TrivialIterator.
|
||||
mult_functor() { }
|
||||
mult_functor(int aa) : a(aa) { }
|
||||
int operator()(int b) const { return a * b; }
|
||||
int a;
|
||||
};
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
dummyT array[] = { dummyT(0), dummyT(1), dummyT(2),
|
||||
dummyT(3), dummyT(4), dummyT(5) };
|
||||
const int N = sizeof(array)/sizeof(dummyT);
|
||||
|
||||
// sanity check, if this doesn't pass the test is buggy
|
||||
boost::random_access_iterator_test(array,N,array);
|
||||
|
||||
// Test the iterator_adaptors
|
||||
{
|
||||
My::iterator i = array;
|
||||
boost::random_access_iterator_test(i, N, array);
|
||||
|
||||
My::const_iterator j = array;
|
||||
boost::random_access_iterator_test(j, N, array);
|
||||
boost::const_nonconst_iterator_test(i, ++j);
|
||||
}
|
||||
// Test transform_iterator
|
||||
{
|
||||
int x[N], y[N];
|
||||
for (int k = 0; k < N; ++k)
|
||||
x[k] = k;
|
||||
std::copy(x, x + N, y);
|
||||
|
||||
for (int k2 = 0; k2 < N; ++k2)
|
||||
x[k2] = x[k2] * 2;
|
||||
|
||||
boost::transform_iterator<mult_functor, int*,
|
||||
boost::iterator<std::random_access_iterator_tag,int> >::type
|
||||
i(y, mult_functor(2));
|
||||
boost::random_access_iterator_test(i, N, x);
|
||||
}
|
||||
// Test indirect_iterator
|
||||
{
|
||||
dummyT* ptr[N];
|
||||
for (int k = 0; k < N; ++k)
|
||||
ptr[k] = array + k;
|
||||
|
||||
typedef dummyT* DummyPtr;
|
||||
typedef boost::indirect_iterators<DummyPtr*, const DummyPtr*,
|
||||
boost::iterator<std::random_access_iterator_tag, DummyPtr>,
|
||||
boost::iterator<std::random_access_iterator_tag, const DummyPtr>,
|
||||
boost::iterator<std::random_access_iterator_tag, dummyT>
|
||||
> Indirect;
|
||||
Indirect::iterator i = ptr;
|
||||
boost::random_access_iterator_test(i, N, array);
|
||||
|
||||
Indirect::const_iterator j = ptr;
|
||||
boost::random_access_iterator_test(j, N, array);
|
||||
|
||||
boost::const_nonconst_iterator_test(i, ++j);
|
||||
}
|
||||
// Test reverse_iterators
|
||||
{
|
||||
dummyT reversed[N];
|
||||
std::copy(array, array + N, reversed);
|
||||
std::reverse(reversed, reversed + N);
|
||||
|
||||
typedef boost::reverse_iterators<dummyT*, const dummyT*,
|
||||
boost::iterator<std::random_access_iterator_tag,dummyT>,
|
||||
boost::iterator<std::random_access_iterator_tag,const dummyT>
|
||||
> Reverse;
|
||||
Reverse::iterator i = reversed + N;
|
||||
boost::random_access_iterator_test(i, N, array);
|
||||
|
||||
Reverse::const_iterator j = reversed + N;
|
||||
boost::random_access_iterator_test(j, N, array);
|
||||
|
||||
boost::const_nonconst_iterator_test(i, ++j);
|
||||
}
|
||||
|
||||
// Test integer_range's iterators
|
||||
{
|
||||
int int_array[] = { 0, 1, 2, 3, 4, 5 };
|
||||
boost::integer_range<int> r(0, 5);
|
||||
boost::random_access_iterator_test(r.begin(), r.size(), int_array);
|
||||
}
|
||||
|
||||
std::cout << "test successful " << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
@@ -617,7 +617,7 @@ uses the three adaptors.
|
||||
|
||||
|
||||
<hr>
|
||||
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->27 Sep 2000<!--webbot bot="Timestamp" endspan i-checksum="14936" --></p>
|
||||
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->17 Jun 2000<!--webbot bot="Timestamp" endspan i-checksum="15055" --></p>
|
||||
<p><EFBFBD> Copyright Jeremy Siek 2000. Permission to copy, use,
|
||||
modify, sell and distribute this document is granted provided this copyright
|
||||
notice appears in all copies. This document is provided "as is"
|
||||
|
@@ -11,8 +11,8 @@
|
||||
|
||||
<h1><img src="../../c++boost.gif" alt="c++boost.gif (8819 bytes)" align="center" width="277" height="86">Header
|
||||
<a href="../../boost/operators.hpp">boost/operators.hpp</a></h1>
|
||||
<p>Header <a href="../../boost/operators.hpp">boost/operators.hpp</a> supplies
|
||||
(in namespace boost) several sets of templates:</p>
|
||||
<p>Header <a href="file:///c:/boost/site/boost/operators.hpp">boost/operators.hpp</a>
|
||||
supplies (in namespace boost) several sets of templates:</p>
|
||||
<ul>
|
||||
<li><a href="#Arithmetic">Arithmetic operators</a>.
|
||||
<li><a href="#deref and helpers">Dereference operators and iterator helpers.</a></li>
|
||||
@@ -43,10 +43,10 @@ additional operators, such as operator>, <=, >=, and +. <a href="
|
||||
forms</a> of the templates are also provided to allow interaction with other
|
||||
types.</p>
|
||||
<p><a href="http://www.boost.org/people/dave_abrahams.htm">Dave Abrahams</a>
|
||||
started the library and contributed the arithmetic operators in <a href="../../boost/operators.hpp">boost/operators.hpp</a>.<br>
|
||||
started the library and contributed the arithmetic operators in <a href="file:///c:/boost/site/boost/operators.hpp">boost/operators.hpp</a>.<br>
|
||||
<a href="http://www.boost.org/people/jeremy_siek.htm">Jeremy Siek</a>
|
||||
contributed the <a href="#deref and helpers">dereference operators and iterator
|
||||
helpers</a> in <a href="../../boost/operators.hpp">boost/operators.hpp</a>.<br>
|
||||
helpers</a> in <a href="file:///c:/boost/site/boost/operators.hpp">boost/operators.hpp</a>.<br>
|
||||
<a href="http://www.boost.org/people/aleksey_gurtovoy.htm">Aleksey Gurtovoy</a>
|
||||
contributed the code to support <a href="#chaining">base class chaining</a>
|
||||
while remaining backward-compatible with old versions of the library.<br>
|
||||
@@ -60,7 +60,7 @@ x >= y,</code> and <code>x <= y</code>. Moreover, unless your class has
|
||||
really surprising behavior, some of these related operators can be defined in
|
||||
terms of others (e.g. <code>x >= y <b><=></b> !(x < y)</code>).
|
||||
Replicating this boilerplate for multiple classes is both tedious and
|
||||
error-prone. The <a href="../../boost/operators.hpp">boost/operators.hpp</a>
|
||||
error-prone. The <a href="file:///c:/boost/site/boost/operators.hpp">boost/operators.hpp</a>
|
||||
templates help by generating operators for you at namespace scope based on other
|
||||
operators you've defined in your class.</p>
|
||||
<a name="two_arg">
|
||||
@@ -585,7 +585,8 @@ complicated than the old one, we think it's worth it to make the library more
|
||||
useful in real world. Alexy Gurtovoy contributed the code which supports the new
|
||||
usage idiom while allowing the library remain backward-compatible.</p>
|
||||
<hr>
|
||||
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->27 Sep 2000<!--webbot bot="Timestamp" endspan i-checksum="14936" --></p>
|
||||
<p>Revised <!--webbot bot="Timestamp" s-type="EDITED" s-format="%d %b %Y" startspan -->03 Aug 2000<!--webbot bot="Timestamp" endspan i-checksum="14750" -->
|
||||
</p>
|
||||
<p><EFBFBD> Copyright David Abrahams and Beman Dawes 1999-2000. Permission to copy,
|
||||
use, modify, sell and distribute this document is granted provided this
|
||||
copyright notice appears in all copies. This document is provided "as
|
||||
|
19
tie.html
19
tie.html
@@ -15,7 +15,7 @@
|
||||
<BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"
|
||||
ALINK="#ff0000">
|
||||
<IMG SRC="../../c++boost.gif"
|
||||
ALT="C++ Boost" width="277" height="86">
|
||||
ALT="C++ Boost">
|
||||
|
||||
<BR Clear>
|
||||
|
||||
@@ -31,11 +31,11 @@ tied<A,B> tie(A& a, B& b);
|
||||
|
||||
<P>
|
||||
This is a utility function that makes it more convenient to work with
|
||||
a function which returns a std::pair<>. The effect of the <TT>tie()</TT>
|
||||
a function which returns a pair. The effect of the <TT>tie()</TT>
|
||||
function is to allow the assignment of the two values of the pair to
|
||||
two separate variables. The idea for this comes from Jaakko
|
||||
Järvi's Binders [<A
|
||||
HREF="../graph/docs/bibliography.html#jaakko_tuple_assign">1</A>].
|
||||
HREF="bibliography.html#jaakko_tuple_assign">1</A>].
|
||||
|
||||
<P>
|
||||
|
||||
@@ -63,7 +63,8 @@ pair of iterators is assigned to the iterator variables <TT>i</TT> and
|
||||
</PRE>
|
||||
|
||||
<P>
|
||||
Here is another example that uses <TT>tie()</TT> for handling operations with <a
|
||||
Here is another example that uses <TT>tie()</TT> for handling
|
||||
operaitons with <a
|
||||
href="http://www.sgi.com/Technology/STL/set.html"><TT>std::set</TT></a>.
|
||||
|
||||
<P>
|
||||
@@ -91,9 +92,9 @@ main(int, char*[])
|
||||
for (int k = 0; k < 2; ++k) {
|
||||
boost::tie(i,inserted) = s.insert(new_vals[k]);
|
||||
if (!inserted)
|
||||
std::cout << *i << " was already in the set." << std::endl;
|
||||
std::cout << *i << " was already in the set." << std::endl;
|
||||
else
|
||||
std::cout << *i << " successfully inserted." << std::endl;
|
||||
std::cout << *i << " successfully inserted." << std::endl;
|
||||
}
|
||||
}
|
||||
{
|
||||
@@ -104,8 +105,8 @@ main(int, char*[])
|
||||
// Using tie() with a return value of pair<iterator,iterator>
|
||||
|
||||
boost::tie(i,end) = std::equal_range(vals, vals + 6, 4);
|
||||
std::cout << "There were " << std::distance(i,end)
|
||||
<< " occurrences of " << *i << "." << std::endl;
|
||||
std::cout << "There were " << std::distance(i,end)
|
||||
<< " occurances of " << *i << "." << std::endl;
|
||||
// Footnote: of course one would normally just use std::count()
|
||||
// to get this information, but that would spoil the example :)
|
||||
}
|
||||
@@ -116,7 +117,7 @@ The output is:
|
||||
<PRE>
|
||||
3 successfully inserted.
|
||||
9 was already in the set.
|
||||
There were 2 occurrences of 4.
|
||||
There were 2 occurances of 4.
|
||||
</PRE>
|
||||
|
||||
<br>
|
||||
|
@@ -126,7 +126,8 @@ is always defined as a compile time constant).</p>
|
||||
<td width="36%"><p align="center">True if T and U are the
|
||||
same type.</p>
|
||||
</td>
|
||||
<td width="27%"> </td>
|
||||
<td width="27%"><p align="center">P</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="37%"><div align="center"><center><pre>is_convertible<T,U>::value</pre>
|
||||
@@ -169,13 +170,15 @@ on a type (see 3.93).</p>
|
||||
<td valign="top" width="37%"><code>is_const<T>::value</code></td>
|
||||
<td valign="top" width="37%">True if type T is top-level
|
||||
const qualified.</td>
|
||||
<td valign="top" width="27%"> </td>
|
||||
<td valign="top" width="27%"><p align="center">P</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="37%"><code>is_volatile<T>::value</code></td>
|
||||
<td valign="top" width="37%">True if type T is top-level
|
||||
volatile qualified.</td>
|
||||
<td valign="top" width="27%"> </td>
|
||||
<td valign="top" width="27%"><p align="center">P</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@@ -345,19 +348,22 @@ as defined by the Standard. </p>
|
||||
<td valign="top" width="45%">True if T is a regular
|
||||
pointer type - including function pointers - but
|
||||
excluding pointers to member functions (3.9.2 p1 and 8.3.1).</td>
|
||||
<td valign="top" width="33%"> </td>
|
||||
<td valign="top" width="33%"><p align="center">P</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="45%"><code>is_member_pointer<T>::value</code></td>
|
||||
<td valign="top" width="45%">True if T is a pointer to a
|
||||
non-static class member (3.9.2 p1 and 8.3.1).</td>
|
||||
<td valign="top" width="33%"> </td>
|
||||
<td valign="top" width="33%"><p align="center">P</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="45%"><code>is_reference<T>::value</code></td>
|
||||
<td valign="top" width="45%">True if T is a reference
|
||||
type (3.9.2 p1 and 8.3.2).</td>
|
||||
<td valign="top" width="33%"> </td>
|
||||
<td valign="top" width="33%"><p align="center">P</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" width="45%"><code>is_class<T>::value</code></td>
|
||||
@@ -601,7 +607,7 @@ familiar standard library algorithms.</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<p>Revised 01 September 2000</p>
|
||||
<p>Revised 08<sup>th</sup> March 2000</p>
|
||||
|
||||
<p><EFBFBD> Copyright boost.org 2000. Permission to copy, use, modify,
|
||||
sell and distribute this document is granted provided this
|
||||
|
@@ -20,7 +20,6 @@
|
||||
#include <typeinfo>
|
||||
|
||||
#include <boost/type_traits.hpp>
|
||||
#include <boost/utility.hpp>
|
||||
#include "type_traits_test.hpp"
|
||||
|
||||
using namespace boost;
|
||||
@@ -163,24 +162,7 @@ struct VD : VB
|
||||
{
|
||||
~VD(){};
|
||||
};
|
||||
//
|
||||
// struct non_pointer:
|
||||
// used to verify that is_pointer does not return
|
||||
// true for class types that implement operator void*()
|
||||
//
|
||||
struct non_pointer
|
||||
{
|
||||
operator void*(){return this;}
|
||||
};
|
||||
//
|
||||
// struct non_empty:
|
||||
// used to verify that is_empty does not emit
|
||||
// spurious warnings or errors.
|
||||
//
|
||||
struct non_empty : boost::noncopyable
|
||||
{
|
||||
int i;
|
||||
};
|
||||
|
||||
|
||||
// Steve: All comments that I (Steve Cleary) have added below are prefixed with
|
||||
// "Steve:" The failures that BCB4 has on the tests are due to Borland's
|
||||
@@ -238,8 +220,6 @@ int main()
|
||||
value_test(false, (is_same<int*, const int*>::value))
|
||||
value_test(false, (is_same<int*, int*const>::value))
|
||||
value_test(false, (is_same<int, int[2]>::value))
|
||||
value_test(false, (is_same<int*, int[2]>::value))
|
||||
value_test(false, (is_same<int[4], int[2]>::value))
|
||||
|
||||
value_test(false, is_const<int>::value)
|
||||
value_test(true, is_const<const int>::value)
|
||||
@@ -383,14 +363,9 @@ int main()
|
||||
|
||||
value_test(false, is_array<int>::value)
|
||||
value_test(false, is_array<int*>::value)
|
||||
value_test(false, is_array<const int*>::value)
|
||||
value_test(false, is_array<const volatile int*>::value)
|
||||
value_test(true, is_array<int[2]>::value)
|
||||
value_test(true, is_array<const int[2]>::value)
|
||||
value_test(true, is_array<const volatile int[2]>::value)
|
||||
value_test(true, is_array<int[2][3]>::value)
|
||||
value_test(true, is_array<UDT[2]>::value)
|
||||
value_test(false, is_array<int(&)[2]>::value)
|
||||
|
||||
typedef void(*f1)();
|
||||
typedef int(*f2)(int);
|
||||
@@ -400,28 +375,15 @@ int main()
|
||||
typedef int (UDT::*mf3)(int);
|
||||
typedef int (UDT::*mf4)(int, float);
|
||||
|
||||
value_test(false, is_const<f1>::value)
|
||||
value_test(false, is_reference<f1>::value)
|
||||
value_test(false, is_array<f1>::value)
|
||||
value_test(false, is_pointer<int>::value)
|
||||
value_test(false, is_pointer<int&>::value)
|
||||
value_test(true, is_pointer<int*>::value)
|
||||
value_test(true, is_pointer<const int*>::value)
|
||||
value_test(true, is_pointer<volatile int*>::value)
|
||||
value_test(true, is_pointer<non_pointer*>::value)
|
||||
// Steve: was 'true', should be 'false', via 3.9.2p3, 3.9.3p1
|
||||
value_test(false, is_pointer<int*const>::value)
|
||||
// Steve: was 'true', should be 'false', via 3.9.2p3, 3.9.3p1
|
||||
value_test(false, is_pointer<int*volatile>::value)
|
||||
// Steve: was 'true', should be 'false', via 3.9.2p3, 3.9.3p1
|
||||
value_test(false, is_pointer<int*const volatile>::value)
|
||||
// JM 02 Oct 2000:
|
||||
value_test(false, is_pointer<non_pointer>::value)
|
||||
value_test(false, is_pointer<int*&>::value)
|
||||
value_test(false, is_pointer<int(&)[2]>::value)
|
||||
value_test(false, is_pointer<int[2]>::value)
|
||||
value_test(false, is_pointer<char[sizeof(void*)]>::value)
|
||||
|
||||
value_test(true, is_pointer<f1>::value)
|
||||
value_test(true, is_pointer<f2>::value)
|
||||
value_test(true, is_pointer<f3>::value)
|
||||
@@ -440,7 +402,6 @@ int main()
|
||||
value_test(true, is_reference<volatile int &>::value)
|
||||
value_test(true, is_reference<r_type>::value)
|
||||
value_test(true, is_reference<cr_type>::value)
|
||||
value_test(true, is_reference<const UDT&>::value)
|
||||
|
||||
value_test(false, is_class<int>::value)
|
||||
value_test(false, is_class<const int>::value)
|
||||
@@ -482,29 +443,19 @@ int main()
|
||||
value_test(false, is_empty<int>::value)
|
||||
value_test(false, is_empty<int*>::value)
|
||||
value_test(false, is_empty<int&>::value)
|
||||
#if defined(__MWERKS__) || defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
#ifdef __MWERKS__
|
||||
// apparent compiler bug causes this to fail to compile:
|
||||
value_fail(false, is_empty<int[2]>::value)
|
||||
#else
|
||||
value_test(false, is_empty<int[2]>::value)
|
||||
#endif
|
||||
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
value_fail(false, is_empty<f1>::value)
|
||||
#else
|
||||
value_test(false, is_empty<f1>::value)
|
||||
#endif
|
||||
value_test(false, is_empty<mf1>::value)
|
||||
value_test(false, is_empty<UDT>::value)
|
||||
value_test(true, is_empty<empty_UDT>::value)
|
||||
value_test(true, is_empty<empty_POD_UDT>::value)
|
||||
#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
value_fail(true, is_empty<empty_union_UDT>::value)
|
||||
#else
|
||||
value_test(true, is_empty<empty_union_UDT>::value)
|
||||
#endif
|
||||
value_test(false, is_empty<enum_UDT>::value)
|
||||
value_test(true, is_empty<boost::noncopyable>::value)
|
||||
value_test(false, is_empty<non_empty>::value)
|
||||
|
||||
value_test(true, has_trivial_constructor<int>::value)
|
||||
value_test(true, has_trivial_constructor<int*>::value)
|
||||
@@ -589,7 +540,7 @@ int main()
|
||||
value_test(false, (boost::is_convertible<Base,Deriverd>::value));
|
||||
value_test(true, (boost::is_convertible<Deriverd,Deriverd>::value));
|
||||
value_test(false, (boost::is_convertible<NonDerived,Base>::value));
|
||||
value_test(false, (boost::is_convertible<boost::noncopyable, int>::value));
|
||||
//value_test(false, (boost::is_convertible<boost::noncopyable, boost::noncopyable>::value));
|
||||
value_test(true, (boost::is_convertible<float,int>::value));
|
||||
#if defined(BOOST_MSVC6_MEMBER_TEMPLATES) || !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
value_test(false, (boost::is_convertible<float,void>::value));
|
||||
@@ -641,3 +592,4 @@ int main()
|
||||
|
||||
|
||||
|
||||
|
||||
|
@@ -33,15 +33,10 @@ struct ct_checker
|
||||
#define BOOST_DO_JOIN2(X, Y) X ## Y
|
||||
#define BOOST_JOIN( X, Y ) BOOST_DO_JOIN( X, Y )
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#define value_test(v, x) ++test_count;\
|
||||
{typedef ct_checker<(x)> this_is_a_compile_time_check_;}\
|
||||
if(!do_compare((int)v,(int)x)){++failures; std::cout << "checking value of " << #x << "...failed" << std::endl;}
|
||||
#else
|
||||
|
||||
#define value_test(v, x) ++test_count;\
|
||||
typedef ct_checker<(x)> BOOST_JOIN(this_is_a_compile_time_check_, __LINE__);\
|
||||
if(!do_compare((int)v,(int)x)){++failures; std::cout << "checking value of " << #x << "...failed" << std::endl;}
|
||||
#endif
|
||||
#define value_fail(v, x) ++test_count; ++failures; std::cout << "checking value of " << #x << "...failed" << std::endl;
|
||||
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
@@ -109,4 +104,3 @@ unsigned test_count = 0;
|
||||
|
||||
|
||||
#endif // BOOST_TYPE_TRAITS_TEST_HPP
|
||||
|
||||
|
@@ -16,11 +16,10 @@
|
||||
<h2>Contents</h2>
|
||||
|
||||
<ul>
|
||||
<li>Function templates <a href="#functions next">next() and prior()</a></li>
|
||||
<li>Template functions <a href="#functions next">next() and prior()</a></li>
|
||||
<li>Class <a href="#Class noncopyable">noncopyable</a></li>
|
||||
<li>Function template <a href="tie.html">tie()</a> and supporting class tied.</li>
|
||||
</ul>
|
||||
<h2> <a name="functions next">Function</a> templates next() and prior()</h2>
|
||||
<h2>Template <a name="functions next">functions next</a>() and prior()</h2>
|
||||
|
||||
<p>Certain data types, such as the C++ Standard Library's forward and
|
||||
bidirectional iterators, do not provide addition and subtraction via operator+()
|
||||
@@ -93,7 +92,7 @@ destructor declarations. He says "Probably this concern is misplaced, becau
|
||||
noncopyable will be used mostly for classes which own resources and thus have non-trivial destruction semantics."</p>
|
||||
<hr>
|
||||
<p>Revised <!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B, %Y" startspan
|
||||
-->28 September, 2000<!--webbot bot="Timestamp" endspan i-checksum="39343"
|
||||
-->26 January, 2000<!--webbot bot="Timestamp" endspan i-checksum="38194"
|
||||
-->
|
||||
</p>
|
||||
<p><EFBFBD> Copyright boost.org 1999. Permission to copy, use, modify, sell and
|
||||
|
Reference in New Issue
Block a user