diff --git a/Assignable.html b/Assignable.html deleted file mode 100644 index c3109df..0000000 --- a/Assignable.html +++ /dev/null @@ -1,116 +0,0 @@ - - - -Assignable - - -C++ Boost - -
-

Assignable

- -

Description

-A type is Assignable if it is possible to assign one object of the type -to another object of that type. - - -

Notation

- - - - - - - - - - - - - - - - -
-T - -is type that is a model of Assignable -
-t - -is an object of type T -
-u - -is an object of type T or possibly const T -
-

Definitions

-

Valid expressions

- - - - - - - - - - - - - - -
-Name - -Expression - -Return type - -Semantics -
-Assignment - -t = u - -T& - -t is equivalent to u -
- - - -

Models

- - - -

See also

-DefaultConstructible -and -CopyConstructible - -
-
- - -
Copyright © 2000 -Jeremy Siek, Univ.of Notre Dame (jsiek@lsc.nd.edu) -
- - - diff --git a/CopyConstructible.html b/CopyConstructible.html deleted file mode 100644 index 4134f5e..0000000 --- a/CopyConstructible.html +++ /dev/null @@ -1,210 +0,0 @@ - - - -CopyConstructible - - -C++ Boost - -
-

CopyConstructible

- -

Description

-A type is CopyConstructible if it is possible to copy objects of that -type. - -

Notation

- - - - - - - - - - - - - - - - -
-T - -is type that is a model of CopyConstructible -
-t - -is an object of type T -
-u - -is an object of type const T -
-

Definitions

-

Valid expressions

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-Name - -Expression - -Return type - -Semantics -
-Copy constructor - -T(t) - -T - -t is equivalent to T(t) -
-Copy constructor - -
-T(u)
-
-
-T - -u is equivalent to T(u) -
-Destructor - -
-t.~T()
-
-
-T - -  -
-Address Operator - -
-&t
-
-
-T* - -denotes the address of t -
-Address Operator - -
-&u
-
-
-T* - -denotes the address of u -
- - - -

Models

- - - -

Concept Checking Class

- -
-  template <class T>
-  struct CopyConstructibleConcept
-  {
-    void constraints() {
-      T a(b);            // require copy constructor
-      T* ptr = &a;       // require address of operator
-      const_constraints(a);
-      ignore_unused_variable_warning(ptr);
-    }
-    void const_constraints(const T& a) {
-      T c(a);            // require const copy constructor
-      const T* ptr = &a; // require const address of operator
-      ignore_unused_variable_warning(c);
-      ignore_unused_variable_warning(ptr);
-    }
-    T b;
-  };
-
- -

See also

-DefaultConstructible -and -Assignable - -
-
- - -
Copyright © 2000 -Jeremy Siek, Univ.of Notre Dame (jsiek@lsc.nd.edu) -
- - - diff --git a/LessThanComparable.html b/LessThanComparable.html deleted file mode 100644 index 294101c..0000000 --- a/LessThanComparable.html +++ /dev/null @@ -1,212 +0,0 @@ - - - - -LessThanComparable - - -C++ Boost - -
-

LessThanComparable

- -

Description

-A type is LessThanComparable if it is ordered: it must -be possible to compare two objects of that type using operator<, and -operator< must be a strict weak ordering relation. - - -

Refinement of

-

Associated types

-

Notation

- - - - - - - - - -
-X - -A type that is a model of LessThanComparable -
-x, y, z - -Object of type X -
-

Definitions

-Consider the relation !(x < y) && !(y < x). If this relation is -transitive (that is, if !(x < y) && !(y < x) && !(y < z) && !(z < y) -implies !(x < z) && !(z < x)), then it satisfies the mathematical -definition of an equivalence relation. In this case, operator< -is a strict weak ordering. -

-If operator< is a strict weak ordering, and if each equivalence class -has only a single element, then operator< is a total ordering. -

Valid expressions

- - - - - - - - - - - - - -
-Name - -Expression - -Type requirements - -Return type -
-Less - -x < y - -  - -Convertible to bool -
- - - -

Expression semantics

- - - - - - - - - - - - - -
-Name - -Expression - -Precondition - -Semantics - -Postcondition -
-Less - -x < y - -x and y are in the domain of < - -  -
- - -

Complexity guarantees

-

Invariants

- - - - - - - - - - - - - -
-Irreflexivity - -x < x must be false. -
-Antisymmetry - -x < y implies !(y < x) [2] -
-Transitivity - -x < y and y < z implies x < z [3] -
-

Models

- -

Notes

-

[1] -Only operator< is fundamental; the other inequality operators -are essentially syntactic sugar. -

[2] -Antisymmetry is a theorem, not an axiom: it follows from -irreflexivity and transitivity. -

[3] -Because of irreflexivity and transitivity, operator< always -satisfies the definition of a partial ordering. The definition of -a strict weak ordering is stricter, and the definition of a -total ordering is stricter still. -

See also

-EqualityComparable, StrictWeakOrdering - - - -
-
- - -
Copyright © 2000 -Jeremy Siek, Univ.of Notre Dame (jsiek@lsc.nd.edu) -
- - - diff --git a/MultiPassInputIterator.html b/MultiPassInputIterator.html deleted file mode 100644 index 99ee2fc..0000000 --- a/MultiPassInputIterator.html +++ /dev/null @@ -1,92 +0,0 @@ - - - -MultiPassInputIterator - -C++ Boost - -
- -

- -MultiPassInputIterator -

- -This concept is a refinement of InputIterator, -adding the requirements that the iterator can be used to make multiple -passes through a range, and that if it1 == it2 and -it1 is dereferenceable then ++it1 == ++it2. The -MultiPassInputIterator is very similar to the ForwardIterator. The -only difference is that a ForwardIterator -requires the reference type to be value_type&, whereas -MultiPassInputIterator is like InputIterator -in that the reference type merely has to be convertible to -value_type. - - -

Design Notes

- -comments by Valentin Bonnard: - -

I think that introducing MultiPassInputIterator isn't the right -solution. Do you also want to define MultiPassBidirectionnalIterator -and MultiPassRandomAccessIterator ? I don't, definitly. It only -confuses the issue. The problem lies into the existing hierarchy of -iterators, which mixes movabillity, modifiabillity and lvalue-ness, -and these are clearly independant. - -

The terms Forward, Bidirectionnal and RandomAccess are about -movabillity and shouldn't be used to mean anything else. In a -completly orthogonal way, iterators can be immutable, mutable, or -neither. Lvalueness of iterators is also orthogonal with -immutabillity. With these clean concepts, your MultiPassInputIterator -is just called a ForwardIterator. - -

-Other translations are:
-std::ForwardIterator -> ForwardIterator & LvalueIterator
-std::BidirectionnalIterator -> BidirectionnalIterator & LvalueIterator
-std::RandomAccessIterator -> RandomAccessIterator & LvalueIterator
- -

-Note that in practice the only operation not allowed on my -ForwardIterator which is allowed on std::ForwardIterator is -&*it. I think that &* is rarely needed in generic code. - -

-reply by Jeremy Siek: - -

-The above analysis by Valentin is right on. Of course, there is -the problem with backward compatibility. The current STL implementations -are based on the old definition of ForwardIterator. The right course -of action is to get ForwardIterator, etc. changed in the C++ standard. -Once that is done we can drop MultiPassInputIterator. - - -
-


- - -
Copyright © 2000 -Jeremy Siek, Univ.of Notre Dame (jsiek@lsc.nd.edu) -
- - - diff --git a/call_traits.htm b/call_traits.htm deleted file mode 100644 index 78cb60f..0000000 --- a/call_traits.htm +++ /dev/null @@ -1,754 +0,0 @@ - - - - - - -Call Traits - - - - -

Header -<boost/call_traits.hpp>

- -

All of the contents of <boost/call_traits.hpp> are -defined inside namespace boost.

- -

The template class call_traits<T> encapsulates the -"best" method to pass a parameter of some type T to or -from a function, and consists of a collection of typedefs defined -as in the table below. The purpose of call_traits is to ensure -that problems like "references to references" -never occur, and that parameters are passed in the most efficient -manner possible (see examples). 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.

- -

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).

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Existing practice

-

call_traits equivalent

-

Description

-

Notes

-

T
- (return by value)

-

call_traits<T>::value_type

-
Defines a type that - represents the "value" of type T. Use this for - functions that return by value, or possibly for stored - values of type T.

2

-

T&
- (return value)

-

call_traits<T>::reference

-
Defines a type that - represents a reference to type T. Use for functions that - would normally return a T&.

1

-

const T&
- (return value)

-

call_traits<T>::const_reference

-
Defines a type that - represents a constant reference to type T. Use for - functions that would normally return a const T&.

1

-

const T&
- (function parameter)

-

call_traits<T>::param_type

-
Defines a type that - represents the "best" way to pass a parameter - of type T to a function.

1,3

-
- -

Notes:

- -
    -
  1. If T is already reference type, then call_traits is - defined such that references to - references do not occur (requires partial - specialization).
  2. -
  3. If T is an array type, then call_traits defines value_type - as a "constant pointer to type" rather than an - "array of type" (requires partial - specialization). Note that if you are using value_type as - a stored value then this will result in storing a "constant - pointer to an array" rather than the array itself. - This may or may not be a good thing depending upon what - you actually need (in other words take care!).
  4. -
  5. If T is a small built in type or a pointer, then param_type - is defined as T const, instead of T - const&. This can improve the ability of the - compiler to optimize loops in the body of the function if - they depend upon the passed parameter, the semantics of - the passed parameter is otherwise unchanged (requires - partial specialization).
  6. -
- -

 

- -

Copy constructibility

- -

The following table defines which call_traits types can always -be copy-constructed from which other types, those entries marked -with a '?' are true only if and only if T is copy constructible:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 

To:

-
From:

T

-

value_type

-

reference

-

const_reference

-

param_type

-
T

?

-

?

-

Y

-

Y

-

Y

-
value_type

?

-

?

-

N

-

N

-

Y

-
reference

?

-

?

-

Y

-

Y

-

Y

-
const_reference

?

-

N

-

N

-

Y

-

Y

-
param_type

?

-

?

-

N

-

N

-

Y

-
- -

 

- -

If T is an assignable type the following assignments are -possible:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 

To:

-
From:

T

-

value_type

-

reference

-

const_reference

-

param_type

-
T

Y

-

Y

-

-

-

-

-

-

-
value_type

Y

-

Y

-

-

-

-

-

-

-
reference

Y

-

Y

-

-

-

-

-

-

-
const_reference

Y

-

Y

-

-

-

-

-

-

-
param_type

Y

-

Y

-

-

-

-

-

-

-
- -

 

- -

Examples

- -

The following table shows the effect that call_traits has on -various types, the table assumes that the compiler supports -partial specialization: if it doesn't then all types behave in -the same way as the entry for "myclass", and call_traits -can not be used with reference or array types.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 

Call_traits type:

-

Original type T

-

value_type

-

reference

-

const_reference

-

param_type

-

Applies to:

-

myclass

-

myclass

-

myclass&

-

const - myclass&

-

myclass - const&

-

All user - defined types.

-

int

-

int

-

int&

-

const int&

-

int const

-

All small - built-in types.

-

int*

-

int*

-

int*&

-

int*const&

-

int* const

-

All - pointer types.

-

int&

-

int&

-

int&

-

const int&

-

int&

-

All - reference types.

-

const int&

-

const int&

-

const int&

-

const int&

-

const int&

-

All - constant-references.

-

int[3]

-

const int*

-

int(&)[3]

-

const int(&)[3]

-

const int* - const

-

All array - types.

-

const int[3]

-

const int*

-

const int(&)[3]

-

const int(&)[3]

-

const int* - const

-

All - constant-array types.

-
- -

 

- -

Example 1:

- -

The following class is a trivial class that stores some type T -by value (see the call_traits_test.cpp -file), the aim is to illustrate how each of the available call_traits -typedefs may be used:

- -
template <class T>
-struct contained
-{
-   // define our typedefs first, arrays are stored by value
-   // so value_type is not the same as result_type:
-   typedef typename boost::call_traits<T>::param_type       param_type;
-   typedef typename boost::call_traits<T>::reference        reference;
-   typedef typename boost::call_traits<T>::const_reference  const_reference;
-   typedef T                                                value_type;
-   typedef typename boost::call_traits<T>::value_type       result_type;
-
-   // stored value:
-   value_type v_;
-   
-   // constructors:
-   contained() {}
-   contained(param_type p) : v_(p){}
-   // return byval:
-   result_type value() { return v_; }
-   // return by_ref:
-   reference get() { return v_; }
-   const_reference const_get()const { return v_; }
-   // pass value:
-   void call(param_type p){}
-
-};
- -

Example 2 (the reference to reference -problem):

- -

Consider the definition of std::binder1st:

- -
template <class Operation> 
-class binder1st : 
-   public unary_function<Operation::second_argument_type, Operation::result_type> 
-{ 
-protected: 
-   Operation op; 
-   Operation::first_argument_type value; 
-public: 
-   binder1st(const Operation& x, const Operation::first_argument_type& y); 
-   Operation::result_type operator()(const Operation::second_argument_type& x) const; 
-}; 
- -

Now consider what happens in the relatively common case that -the functor takes its second argument as a reference, that -implies that Operation::second_argument_type is a -reference type, operator() will now end up taking a -reference to a reference as an argument, and that is not -currently legal. The solution here is to modify operator() -to use call_traits:

- -
Operation::result_type operator()(call_traits<Operation::second_argument_type>::param_type x) const;
- -

Now in the case that Operation::second_argument_type -is a reference type, the argument is passed as a reference, and -the no "reference to reference" occurs.

- -

Example 3 (the make_pair problem):

- -

If we pass the name of an array as one (or both) arguments to std::make_pair, -then template argument deduction deduces the passed parameter as -"const reference to array of T", this also applies to -string literals (which are really array literals). Consequently -instead of returning a pair of pointers, it tries to return a -pair of arrays, and since an array type is not copy-constructible -the code fails to compile. One solution is to explicitly cast the -arguments to make_pair to pointers, but call_traits provides a -better (i.e. automatic) solution (and one that works safely even -in generic code where the cast might do the wrong thing):

- -
template <class T1, class T2>
-std::pair<
-   typename boost::call_traits<T1>::value_type, 
-   typename boost::call_traits<T2>::value_type> 
-      make_pair(const T1& t1, const T2& t2)
-{
-   return std::pair<
-      typename boost::call_traits<T1>::value_type, 
-      typename boost::call_traits<T2>::value_type>(t1, t2);
-}
- -

Here, the deduced argument types will be automatically -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.

- -

Example 4 (optimising fill):

- -

The call_traits template will "optimize" the passing -of a small built-in type as a function parameter, this mainly has -an effect when the parameter is used within a loop body. In the -following example (see algo_opt_examples.cpp), -a version of std::fill is optimized in two ways: if the type -passed is a single byte built-in type then std::memset is used to -effect the fill, otherwise a conventional C++ implemention is -used, but with the passed parameter "optimized" using -call_traits:

- -
namespace detail{
-
-template <bool opt>
-struct filler
-{
-   template <typename I, typename T>
-   static void do_fill(I first, I last, typename boost::call_traits<T>::param_type val);
-   {
-      while(first != last)
-      {
-         *first = val;
-         ++first;
-      }
-   }
-};
-
-template <>
-struct filler<true>
-{
-   template <typename I, typename T>
-   static void do_fill(I first, I last, T val)
-   {
-      memset(first, val, last-first);
-   }
-};
-
-}
-
-template <class I, class T>
-inline void fill(I first, I last, const T& val)
-{
-   enum{ can_opt = boost::is_pointer<I>::value
-                   && boost::is_arithmetic<T>::value
-                   && (sizeof(T) == 1) };
-   typedef detail::filler<can_opt> filler_t;
-   filler_t::template do_fill<I,T>(first, last, val);
-}
- -

Footnote: the reason that this is "optimal" for -small built-in types is that with the value passed as "T -const" instead of "const T&" the compiler is -able to tell both that the value is constant and that it is free -of aliases. With this information the compiler is able to cache -the passed value in a register, unroll the loop, or use -explicitly parallel instructions: if any of these are supported. -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.

- -

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.

- -

Rationale

- -

The following notes are intended to briefly describe the -rational behind choices made in call_traits.

- -

All user-defined types follow "existing practice" -and need no comment.

- -

Small built-in types (what the standard calls fundamental -types [3.9.1]) differ from existing practice only in the param_type -typedef. In this case passing "T const" is compatible -with existing practice, but may improve performance in some cases -(see Example 4), in any case this should never -be any worse than existing practice.

- -

Pointers follow the same rational as small built-in types.

- -

For reference types the rational follows Example -2 - references to references are not allowed, so the call_traits -members must be defined such that these problems do not occur. -There is a proposal to modify the language such that "a -reference to a reference is a reference" (issue #106, -submitted by Bjarne Stroustrup), call_traits<T>::value_type -and call_traits<T>::param_type both provide the same effect -as that proposal, without the need for a language change (in -other words it's a workaround).

- -

For array types, a function that takes an array as an argument -will degrade the array type to a pointer type: this means that -the type of the actual parameter is different from its declared -type, something that can cause endless problems in template code -that relies on the declared type of a parameter. For example:

- -
template <class T>
-struct A
-{
-   void foo(T t);
-};
- -

In this case if we instantiate A<int[2]> -then the declared type of the parameter passed to member function -foo is int[2], but it's actual type is const int*, if we try to -use the type T within the function body, then there is a strong -likelyhood that our code will not compile:

- -
template <class T>
-void A<T>::foo(T t)
-{
-   T dup(t); // doesn't compile for case that T is an array.
-}
- -

By using call_traits the degradation from array to pointer is -explicit, and the type of the parameter is the same as it's -declared type:

- -
template <class T>
-struct A
-{
-   void foo(call_traits<T>::value_type t);
-};
-
-template <class T>
-void A<T>::foo(call_traits<T>::value_type t)
-{
-   call_traits<T>::value_type dup(t); // OK even if T is an array type.
-}
- -

For value_type (return by value), again only a pointer may be -returned, not a copy of the whole array, and again call_traits -makes the degradation explicit. The value_type member is useful -whenever an array must be explicitly degraded to a pointer - Example 3 provides the test case (Footnote: the -array specialisation for call_traits is the least well understood -of all the call_traits specialisations, if the given semantics -cause specific problems for you, or don't solve a particular -array-related problem, then I would be interested to hear about -it. Most people though will probably never need to use this -specialisation).

- -
- -

Revised 01 September 2000

- -

© Copyright boost.org 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" without express or implied warranty, and with -no claim as to its suitability for any purpose.

- -

Based on contributions by Steve Cleary, Beman Dawes, Howard -Hinnant and John Maddock.

- -

Maintained by John -Maddock, the latest version of this file can be found at www.boost.org, and the boost -discussion list at www.egroups.com/list/boost.

- -

.

- -

 

- -

 

- - diff --git a/call_traits_test.cpp b/call_traits_test.cpp deleted file mode 100644 index 762d8b8..0000000 --- a/call_traits_test.cpp +++ /dev/null @@ -1,375 +0,0 @@ - // boost::compressed_pair test program - - // (C) Copyright 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. - -// standalone test program for -// 03 Oct 2000: -// Enabled extra tests for VC6. - -#include -#include -#include -#include -#include -#include - -#include -// -// struct contained models a type that contains a type (for example std::pair) -// arrays are contained by value, and have to be treated as a special case: -// -template -struct contained -{ - // define our typedefs first, arrays are stored by value - // so value_type is not the same as result_type: - typedef typename boost::call_traits::param_type param_type; - typedef typename boost::call_traits::reference reference; - typedef typename boost::call_traits::const_reference const_reference; - typedef T value_type; - typedef typename boost::call_traits::value_type result_type; - - // stored value: - value_type v_; - - // constructors: - contained() {} - contained(param_type p) : v_(p){} - // return byval: - result_type value()const { return v_; } - // return by_ref: - reference get() { return v_; } - const_reference const_get()const { return v_; } - // pass value: - void call(param_type p){} - -}; - -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -template -struct contained -{ - typedef typename boost::call_traits::param_type param_type; - typedef typename boost::call_traits::reference reference; - typedef typename boost::call_traits::const_reference const_reference; - typedef T value_type[N]; - typedef typename boost::call_traits::value_type result_type; - - value_type v_; - - contained(param_type p) - { - std::copy(p, p+N, v_); - } - // return byval: - result_type value()const { return v_; } - // return by_ref: - reference get() { return v_; } - const_reference const_get()const { return v_; } - void call(param_type p){} -}; -#endif - -template -contained::value_type> wrap(const T& t) -{ - typedef typename boost::call_traits::value_type ct; - return contained(t); -} - -namespace test{ - -template -std::pair< - typename boost::call_traits::value_type, - typename boost::call_traits::value_type> - make_pair(const T1& t1, const T2& t2) -{ - return std::pair< - typename boost::call_traits::value_type, - typename boost::call_traits::value_type>(t1, t2); -} - -} // namespace test - -using namespace std; - -// -// struct call_traits_checker: -// verifies behaviour of contained example: -// -template -struct call_traits_checker -{ - typedef typename boost::call_traits::param_type param_type; - void operator()(param_type); -}; - -template -void call_traits_checker::operator()(param_type p) -{ - T t(p); - contained c(t); - cout << "checking contained<" << typeid(T).name() << ">..." << endl; - assert(t == c.value()); - assert(t == c.get()); - assert(t == c.const_get()); - - //cout << "typeof contained<" << typeid(T).name() << ">::v_ is: " << typeid(&contained::v_).name() << endl; - cout << "typeof contained<" << typeid(T).name() << ">::value() is: " << typeid(&contained::value).name() << endl; - cout << "typeof contained<" << typeid(T).name() << ">::get() is: " << typeid(&contained::get).name() << endl; - cout << "typeof contained<" << typeid(T).name() << ">::const_get() is: " << typeid(&contained::const_get).name() << endl; - cout << "typeof contained<" << typeid(T).name() << ">::call() is: " << typeid(&contained::call).name() << endl; - cout << endl; -} - -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -template -struct call_traits_checker -{ - typedef typename boost::call_traits::param_type param_type; - void operator()(param_type t) - { - contained c(t); - cout << "checking contained<" << typeid(T[N]).name() << ">..." << endl; - unsigned int i = 0; - for(i = 0; i < N; ++i) - assert(t[i] == c.value()[i]); - for(i = 0; i < N; ++i) - assert(t[i] == c.get()[i]); - for(i = 0; i < N; ++i) - assert(t[i] == c.const_get()[i]); - - cout << "typeof contained<" << typeid(T[N]).name() << ">::v_ is: " << typeid(&contained::v_).name() << endl; - cout << "typeof contained<" << typeid(T[N]).name() << ">::value is: " << typeid(&contained::value).name() << endl; - cout << "typeof contained<" << typeid(T[N]).name() << ">::get is: " << typeid(&contained::get).name() << endl; - cout << "typeof contained<" << typeid(T[N]).name() << ">::const_get is: " << typeid(&contained::const_get).name() << endl; - cout << "typeof contained<" << typeid(T[N]).name() << ">::call is: " << typeid(&contained::call).name() << endl; - cout << endl; - } -}; -#endif - -// -// check_wrap: -template -void check_wrap(const contained& w, const U& u) -{ - cout << "checking contained<" << typeid(T).name() << ">..." << endl; - assert(w.value() == u); -} - -// -// check_make_pair: -// verifies behaviour of "make_pair": -// -template -void check_make_pair(T c, U u, V v) -{ - cout << "checking std::pair<" << typeid(c.first).name() << ", " << typeid(c.second).name() << ">..." << endl; - assert(c.first == u); - assert(c.second == v); - cout << endl; -} - - -struct comparible_UDT -{ - int i_; - comparible_UDT() : i_(2){} - bool operator == (const comparible_UDT& v){ return v.i_ == i_; } -}; - -int main(int argc, char *argv[ ]) -{ - call_traits_checker c1; - comparible_UDT u; - c1(u); - call_traits_checker c2; - int i = 2; - c2(i); - int* pi = &i; -#if defined(BOOST_MSVC6_MEMBER_TEMPLATES) || !defined(BOOST_NO_MEMBER_TEMPLATES) - call_traits_checker c3; - c3(pi); - call_traits_checker c4; - c4(i); - call_traits_checker c5; - c5(i); -#if !defined (BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) - int a[2] = {1,2}; - call_traits_checker c6; - c6(a); -#endif -#endif - - check_wrap(wrap(2), 2); - const char ca[4] = "abc"; - // compiler can't deduce this for some reason: - //check_wrap(wrap(ca), ca); -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - check_wrap(wrap(a), a); - check_make_pair(test::make_pair(a, a), a, a); -#endif - - // cv-qualifiers applied to reference types should have no effect - // declare these here for later use with is_reference and remove_reference: - typedef int& r_type; - typedef const r_type cr_type; - - type_test(comparible_UDT, boost::call_traits::value_type) - type_test(comparible_UDT&, boost::call_traits::reference) - type_test(const comparible_UDT&, boost::call_traits::const_reference) - type_test(const comparible_UDT&, boost::call_traits::param_type) - type_test(int, boost::call_traits::value_type) - type_test(int&, boost::call_traits::reference) - type_test(const int&, boost::call_traits::const_reference) - type_test(const int, boost::call_traits::param_type) - type_test(int*, boost::call_traits::value_type) - type_test(int*&, boost::call_traits::reference) - type_test(int*const&, boost::call_traits::const_reference) - type_test(int*const, boost::call_traits::param_type) -#if defined(BOOST_MSVC6_MEMBER_TEMPLATES) || !defined(BOOST_NO_MEMBER_TEMPLATES) - type_test(int&, boost::call_traits::value_type) - type_test(int&, boost::call_traits::reference) - type_test(const int&, boost::call_traits::const_reference) - type_test(int&, boost::call_traits::param_type) -#if !(defined(__GNUC__) && (__GNUC__ < 3)) - type_test(int&, boost::call_traits::value_type) - type_test(int&, boost::call_traits::reference) - type_test(const int&, boost::call_traits::const_reference) - type_test(int&, boost::call_traits::param_type) -#else - std::cout << "Your compiler cannot instantiate call_traits, skipping four tests (4 errors)" << std::endl; - failures += 4; - test_count += 4; -#endif - type_test(const int&, boost::call_traits::value_type) - type_test(const int&, boost::call_traits::reference) - type_test(const int&, boost::call_traits::const_reference) - type_test(const int&, boost::call_traits::param_type) -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - type_test(const int*, boost::call_traits::value_type) - type_test(int(&)[3], boost::call_traits::reference) - type_test(const int(&)[3], boost::call_traits::const_reference) - type_test(const int*const, boost::call_traits::param_type) - type_test(const int*, boost::call_traits::value_type) - type_test(const int(&)[3], boost::call_traits::reference) - type_test(const int(&)[3], boost::call_traits::const_reference) - type_test(const int*const, boost::call_traits::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; - test_count += 20; -#endif - - return check_result(argc, argv); -} - -// -// define call_traits tests to check that the assertions in the docs do actually work -// this is an instantiate only set of tests: -// -template -struct call_traits_test -{ - typedef ::boost::call_traits ct; - typedef typename ct::param_type param_type; - typedef typename ct::reference reference; - typedef typename ct::const_reference const_reference; - typedef typename ct::value_type value_type; - static void assert_construct(param_type val); -}; - -template -void call_traits_test::assert_construct(typename call_traits_test::param_type val) -{ - // - // this is to check that the call_traits assertions are valid: - T t(val); - value_type v(t); - reference r(t); - const_reference cr(t); - param_type p(t); - value_type v2(v); - value_type v3(r); - value_type v4(p); - reference r2(v); - reference r3(r); - const_reference cr2(v); - const_reference cr3(r); - const_reference cr4(cr); - const_reference cr5(p); - param_type p2(v); - param_type p3(r); - param_type p4(p); -} -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -template -struct call_traits_test -{ - typedef ::boost::call_traits ct; - typedef typename ct::param_type param_type; - typedef typename ct::reference reference; - typedef typename ct::const_reference const_reference; - typedef typename ct::value_type value_type; - static void assert_construct(param_type val); -}; - -template -void call_traits_test::assert_construct(typename boost::call_traits::param_type val) -{ - // - // this is to check that the call_traits assertions are valid: - T t; - value_type v(t); - value_type v5(val); - reference r = t; - const_reference cr = t; - reference r2 = r; - #ifndef __BORLANDC__ - // C++ Builder buglet: - const_reference cr2 = r; - #endif - param_type p(t); - value_type v2(v); - const_reference cr3 = cr; - value_type v3(r); - value_type v4(p); - param_type p2(v); - param_type p3(r); - param_type p4(p); -} -#endif //BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -// -// now check call_traits assertions by instantiating call_traits_test: -template struct call_traits_test; -template struct call_traits_test; -template struct call_traits_test; -#if defined(BOOST_MSVC6_MEMBER_TEMPLATES) || !defined(BOOST_NO_MEMBER_TEMPLATES) -template struct call_traits_test; -template struct call_traits_test; -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -template struct call_traits_test; -#endif -#endif - -#ifdef BOOST_MSVC -unsigned int expected_failures = 10; -#elif defined(__BORLANDC__) -unsigned int expected_failures = 2; -#elif defined(__GNUC__) -unsigned int expected_failures = 4; -#else -unsigned int expected_failures = 0; -#endif - - diff --git a/compressed_pair.htm b/compressed_pair.htm deleted file mode 100644 index d63af7f..0000000 --- a/compressed_pair.htm +++ /dev/null @@ -1,92 +0,0 @@ - - - - - - -Header <boost/compressed_pair.hpp> - - - - -

Header -<boost/compressed_pair.hpp>

- -

All of the contents of <boost/compressed_pair.hpp> are -defined inside namespace boost.

- -

The class compressed pair is very similar to std::pair, but if -either of the template arguments are empty classes, then the -"empty member optimisation" is applied to compress the -size of the pair.

- -
template <class T1, class T2>
-class compressed_pair
-{
-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);
-	explicit compressed_pair(first_param_type x);
-	explicit compressed_pair(second_param_type y);
-
-	first_reference       first();
-	first_const_reference first() const;
-
-	second_reference       second();
-	second_const_reference second() const;
-
-	void swap(compressed_pair& y);
-};
- -

The two members of the pair can be accessed using the member -functions first() and second(). Note that not all member -functions can be instantiated for all template parameter types. -In particular compressed_pair can be instantiated for reference -and array types, however in these cases the range of constructors -that can be used are limited. If types T1 and T2 are the same -type, then there is only one version of the single-argument -constructor, and this constructor initialises both values in the -pair to the passed value.

- -

Note that compressed_pair can not be instantiated if either of -the template arguments is an enumerator type, unless there is -compiler support for boost::is_enum, or if boost::is_enum is -specialised for the enumerator type.

- -

Finally, compressed_pair requires compiler support for partial -specialisation of class templates - without that support -compressed_pair behaves just like std::pair.

- -
- -

Revised 08 March 2000

- -

© Copyright boost.org 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" without express or implied warranty, and with -no claim as to its suitability for any purpose.

- -

Based on contributions by Steve Cleary, Beman Dawes, Howard -Hinnant and John Maddock.

- -

Maintained by John -Maddock, the latest version of this file can be found at www.boost.org, and the boost -discussion list at www.egroups.com/list/boost.

- -

 

- - diff --git a/compressed_pair_test.cpp b/compressed_pair_test.cpp deleted file mode 100644 index cc03544..0000000 --- a/compressed_pair_test.cpp +++ /dev/null @@ -1,162 +0,0 @@ - // boost::compressed_pair test program - - // (C) Copyright 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. - -// standalone test program for -// Revised 03 Oct 2000: -// Enabled tests for VC6. - -#include -#include -#include - -#include -#include - -using namespace boost; - -namespace boost { -#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION -template <> struct is_empty -{ static const bool value = true; }; -template <> struct is_empty -{ static const bool value = true; }; -template <> struct is_POD -{ static const bool value = true; }; -#else -template <> struct is_empty -{ enum{ value = true }; }; -template <> struct is_empty -{ enum{ value = true }; }; -template <> struct is_POD -{ enum{ value = true }; }; -#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(int argc, char *argv[ ]) -{ - compressed_pair cp1(1, 1.3); - assert(cp1.first() == 1); - assert(cp1.second() == 1.3); - compressed_pair cp1b(2, 2.3); - assert(cp1b.first() == 2); - assert(cp1b.second() == 2.3); - swap(cp1, cp1b); - assert(cp1b.first() == 1); - assert(cp1b.second() == 1.3); - assert(cp1.first() == 2); - assert(cp1.second() == 2.3); - compressed_pair cp1c(non_empty1(9)); - assert(cp1c.second() == non_empty2()); - assert(cp1c.first() == non_empty1(9)); - compressed_pair cp1d(non_empty2(9)); - assert(cp1d.second() == non_empty2(9)); - assert(cp1d.first() == non_empty1()); - - compressed_pair cp1e(cp1); - - compressed_pair cp2(2); - assert(cp2.second() == 2); - compressed_pair cp3(1); - assert(cp3.first() ==1); - compressed_pair cp4; - compressed_pair cp5; - compressed_pair cp9(empty_UDT()); - compressed_pair cp10(1); - assert(cp10.first() == 1); -#if defined(BOOST_MSVC6_MEMBER_TEMPLATES) || !defined(BOOST_NO_MEMBER_TEMPLATES) || !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) - int i = 0; - compressed_pair cp6(i,i); - assert(cp6.first() == i); - assert(cp6.second() == i); - assert(&cp6.first() == &i); - assert(&cp6.second() == &i); - compressed_pair cp7; - cp7.first(); - double* pd = cp7.second(); -#endif - value_test(true, (sizeof(compressed_pair) < sizeof(std::pair))) - value_test(true, (sizeof(compressed_pair) < sizeof(std::pair))) - value_test(true, (sizeof(compressed_pair) < sizeof(std::pair))) - value_test(true, (sizeof(compressed_pair) < sizeof(std::pair))) - value_test(true, (sizeof(compressed_pair >) < sizeof(std::pair >))) - - return check_result(argc, argv); -} - -// -// instanciate some compressed pairs: -#ifdef __MWERKS__ -template class compressed_pair; -template class compressed_pair; -template class compressed_pair; -template class compressed_pair; -template class compressed_pair; -template class compressed_pair; -#else -template class boost::compressed_pair; -template class boost::compressed_pair; -template class boost::compressed_pair; -template class boost::compressed_pair; -template class boost::compressed_pair; -template class boost::compressed_pair; -#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::first(); -template int& compressed_pair::second(); -#if !(defined(__GNUC__) && (__GNUC__ == 2) && (__GNUC_MINOR__ < 95)) -template compressed_pair::compressed_pair(int&); -#endif -template compressed_pair::compressed_pair(call_traits::param_type,int&); -// -// and then arrays: -#ifndef __BORLANDC__ -template call_traits::reference compressed_pair::second(); -#endif -template call_traits::reference compressed_pair::first(); -#if !(defined(__GNUC__) && (__GNUC__ == 2) && (__GNUC_MINOR__ < 95)) -template compressed_pair::compressed_pair(call_traits::param_type); -#endif -template compressed_pair::compressed_pair(); -#endif // __MWERKS__ -#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - -#ifdef __BORLANDC__ -// can't handle both types empty: -unsigned int expected_failures = 4; -#elif defined(__GNUC__) -// no zero sized base classes: -unsigned int expected_failures = 4; -#else -unsigned int expected_failures = 0; -#endif - - - - diff --git a/counting_iterator.htm b/counting_iterator.htm deleted file mode 100644 index e337044..0000000 --- a/counting_iterator.htm +++ /dev/null @@ -1,325 +0,0 @@ - - - - - - -Counting Iterator Adaptor Documentation - - - - -c++boost.gif (8819 bytes) - -

Counting Iterator Adaptor

- -Defined in header -boost/counting_iterator.hpp - -

-How would you fill up a vector with the numbers zero -through one hundred using std::copy()? The -only iterator operation missing from builtin integer types is an -operator*() that returns the current -value of the integer. The counting iterator adaptor adds this crucial piece of -functionality to whatever type it wraps. One can use the -counting iterator adaptor not only with integer types, but with any -type that is Incrementable (see type requirements below). The -following pseudo-code shows the general idea of how the -counting iterator is implemented. -

- -
-  // inside a hypothetical counting_iterator class...
-  typedef Incrementable value_type;
-  value_type counting_iterator::operator*() const {
-    return this->base; // no dereference!
-  }
-
- -All of the other operators of the counting iterator behave in the same -fashion as the Incrementable base type. - -

Synopsis

- -
-namespace boost {
-  template <class Incrementable>
-  struct counting_iterator_traits;
-
-  template <class Incrementable>
-  struct counting_iterator_generator;
-
-  template <class Incrementable>
-  typename counting_iterator_generator<Incrementable>::type
-  make_counting_iterator(Incrementable x);
-}
-
- -
- -

The Counting Iterator Type -Generator

- -The class template counting_iterator_generator<Incrementable> is a type generator for counting iterators. - -
-template <class Incrementable>
-class counting_iterator_generator
-{
-public:
-    typedef iterator_adaptor<...> type;
-};
-
- -

Example

- -In this example we use the counting iterator generator to create a -counting iterator, and count from zero to four. - -
-#include <boost/config.hpp>
-#include <iostream>
-#include <boost/counting_iterator.hpp>
-
-int main(int, char*[])
-{
-  // Example of using counting_iterator_generator
-  std::cout << "counting from 0 to 4:" << std::endl;
-  boost::counting_iterator_generator<int>::type first(0), last(4);
-  std::copy(first, last, std::ostream_iterator<int>(std::cout, " "));
-  std::cout << std::endl;
-
-  // to be continued...
-
-The output from this part is: -
-counting from 0 to 4:
-0 1 2 3 
-
- -

Template Parameters

- - - - - - - - - - - -
ParameterDescription
IncrementableThe type being wrapped by the adaptor.
- -

Model of

- -If the Incrementable type has all of the functionality of a -Random -Access Iterator except the operator*(), then the counting -iterator will be a model of Random -Access Iterator. If the Incrementable type has less -functionality, then the counting iterator will have correspondingly -less functionality. - -

Type Requirements

- -The Incrementable type must be Default -Constructible, Copy -Constructible, and Assignable. -Also, the Incrementable type must provide access to an -associated difference_type and iterator_category -through the counting_iterator_traits -class. - -

-Furthermore, if you wish to create a counting iterator that is a Forward -Iterator, then the following expressions must be valid: -

-Incrementable i, j;
-++i         // pre-increment
-i == j      // operator equal
-
-If you wish to create a counting iterator that is a -Bidirectional Iterator, then pre-decrement is also required: -
---i
-
-If you wish to create a counting iterator that is a Random -Access Iterator, then these additional expressions are also required: -
-counting_iterator_traits<Incrementable>::difference_type n;
-i += n
-n = i - j
-i < j
-
- - - -

Members

- -The counting iterator type implements the member functions and -operators required of the Random -Access Iterator concept. In addition it has the following -constructor: - -
-counting_iterator_generator::type(const Incrementable& i)
-
- -

-


-

- - -

The Counting Iterator Object Generator

- -
-template <class Incrementable>
-typename counting_iterator_generator<Incrementable>::type
-make_counting_iterator(Incrementable base);
-
- -An object -generator function that provides a convenient way to create counting -iterators.

- - - -

Example

- -In this example we count from negative five to positive five, this -time using the make_counting_iterator() function to save some -typing. - -
-  // continuing from previous example...
-
-  std::cout << "counting from -5 to 4:" << std::endl;
-  std::copy(boost::make_counting_iterator(-5),
-	    boost::make_counting_iterator(5),
-	    std::ostream_iterator<int>(std::cout, " "));
-  std::cout << std::endl;
-
-  // to be continued...
-
-The output from this part is: -
-counting from -5 to 4:
--5 -4 -3 -2 -1 0 1 2 3 4 
-
- -In the next example we create an array of numbers, and then create a -second array of pointers, where each pointer is the address of a -number in the first array. The counting iterator makes it easy to do -this since dereferencing a counting iterator that is wrapping an -iterator over the array of numbers just returns a pointer to the -current location in the array. We then use the indirect iterator adaptor to print -out the number in the array by accessing the numbers through the array -of pointers. - -
-  // continuing from previous example...
-
-  const int N = 7;
-  std::vector<int> numbers;
-  // Fill "numbers" array with [0,N)
-  std::copy(boost::make_counting_iterator(0), boost::make_counting_iterator(N),
-	    std::back_inserter(numbers));
-
-  std::vector<std::vector<int>::iterator> pointers;
-
-  // Use counting iterator to fill in the array of pointers.
-  std::copy(boost::make_counting_iterator(numbers.begin()),
-	    boost::make_counting_iterator(numbers.end()),
-	    std::back_inserter(pointers));
-
-  // Use indirect iterator to print out numbers by accessing
-  // them through the array of pointers.
-  std::cout << "indirectly printing out the numbers from 0 to " 
-	    << N << std::endl;
-  std::copy(boost::make_indirect_iterator(pointers.begin()),
-	    boost::make_indirect_iterator(pointers.end()),
-	    std::ostream_iterator<int>(std::cout, " "));
-  std::cout << std::endl;
-
-The output is: -
-indirectly printing out the numbers from 0 to 7
-0 1 2 3 4 5 6 
-
- -
- -

Counting Iterator Traits

- -The counting iterator adaptor needs to determine the appropriate -difference_type and iterator_category to use based on the -Incrementable type supplied by the user. The -counting_iterator_traits class provides these types. If the -Incrementable type is an integral type or an iterator, these types -will be correctly deduced by the counting_iterator_traits provided by -the library. Otherwise, the user must specialize -counting_iterator_traits for her type or add nested typedefs to -her type to fulfill the needs of - -std::iterator_traits. - -

The following pseudocode describes how the counting_iterator_traits are determined: - -

-template <class Incrementable>
-struct counting_iterator_traits
-{
-  if (numeric_limits<Incrementable>::is_specialized) {
-    if (!numeric_limits<Incrementable>::is_integral)
-       COMPILE_TIME_ERROR;
-
-    if (!numeric_limits<Incrementable>::is_bounded
-        && numeric_limits<Incrementable>::is_signed) {
-        typedef Incrementable difference_type;
-    }
-    else if (numeric_limits<Incrementable>::is_integral) {
-        typedef next-larger-signed-type-or-intmax_t difference_type;
-    }
-    typedef std::random_access_iterator_tag iterator_category;   
-  } else {
-    typedef std::iterator_traits<Incrementable>::difference_type difference_type;
-    typedef std::iterator_traits<Incrementable>::iterator_category iterator_category;
-  }
-};
-
- -

The italicized sections above are implementation details, but it is important -to know that the difference_type for integral types is selected so that -it can always represent the difference between two values if such a built-in -integer exists. On platforms with a working std::numeric_limits -implementation, the difference_type for any variable-length signed -integer type T is T itself. - -


-

Revised 15 Feb 2001

-

© 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" -without express or implied warranty, and with no claim as to its suitability for -any purpose.

- - - - - - - diff --git a/counting_iterator_example.cpp b/counting_iterator_example.cpp deleted file mode 100644 index 9513c06..0000000 --- a/counting_iterator_example.cpp +++ /dev/null @@ -1,53 +0,0 @@ -// (C) Copyright Jeremy Siek 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. - - -#include -#include -#include -#include -#include -#include - -int main(int, char*[]) -{ - // Example of using counting_iterator_generator - std::cout << "counting from 0 to 4:" << std::endl; - boost::counting_iterator_generator::type first(0), last(4); - std::copy(first, last, std::ostream_iterator(std::cout, " ")); - std::cout << std::endl; - - // Example of using make_counting_iterator() - std::cout << "counting from -5 to 4:" << std::endl; - std::copy(boost::make_counting_iterator(-5), - boost::make_counting_iterator(5), - std::ostream_iterator(std::cout, " ")); - std::cout << std::endl; - - // Example of using counting iterator to create an array of pointers. - const int N = 7; - std::vector numbers; - // Fill "numbers" array with [0,N) - std::copy(boost::make_counting_iterator(0), boost::make_counting_iterator(N), - std::back_inserter(numbers)); - - std::vector::iterator> pointers; - - // Use counting iterator to fill in the array of pointers. - std::copy(boost::make_counting_iterator(numbers.begin()), - boost::make_counting_iterator(numbers.end()), - std::back_inserter(pointers)); - - // Use indirect iterator to print out numbers by accessing - // them through the array of pointers. - std::cout << "indirectly printing out the numbers from 0 to " - << N << std::endl; - std::copy(boost::make_indirect_iterator(pointers.begin()), - boost::make_indirect_iterator(pointers.end()), - std::ostream_iterator(std::cout, " ")); - std::cout << std::endl; - - return 0; -} diff --git a/counting_iterator_test.cpp b/counting_iterator_test.cpp deleted file mode 100644 index 0032dda..0000000 --- a/counting_iterator_test.cpp +++ /dev/null @@ -1,263 +0,0 @@ -// (C) Copyright David Abrahams 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 -// 16 Feb 2001 Added a missing const. Made the tests run (somewhat) with -// plain MSVC again. (David Abrahams) -// 11 Feb 2001 #if 0'd out use of counting_iterator on non-numeric types in -// MSVC without STLport, so that the other tests may proceed -// (David Abrahams) -// 04 Feb 2001 Added use of iterator_tests.hpp (David Abrahams) -// 28 Jan 2001 Removed not_an_iterator detritus (David Abrahams) -// 24 Jan 2001 Initial revision (David Abrahams) - -#include -#ifdef BOOST_MSVC -# pragma warning(disable:4786) // identifier truncated in debug info -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifndef BOOST_NO_LIMITS -# include -#endif -#ifndef BOOST_NO_SLIST -# include -#endif - -template struct is_numeric -{ - enum { value = -#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS - std::numeric_limits::is_specialized -#else - // Causes warnings with GCC, but how else can I detect numeric types at - // compile-time? - (boost::is_convertible::value && - boost::is_convertible::value) -#endif - }; -}; - -// Special tests for RandomAccess CountingIterators. -template -void category_test( - CountingIterator start, - CountingIterator finish, - std::random_access_iterator_tag) -{ - typedef typename - boost::detail::iterator_traits::difference_type - difference_type; - difference_type distance = boost::detail::distance(start, finish); - - // Pick a random position internal to the range - difference_type offset = (unsigned)rand() % distance; - assert(offset >= 0); - CountingIterator internal = start; - std::advance(internal, offset); - - // Try some binary searches on the range to show that it's ordered - assert(std::binary_search(start, finish, *internal)); - CountingIterator x,y; - boost::tie(x,y) = std::equal_range(start, finish, *internal); - assert(boost::detail::distance(x, y) == 1); - - // Show that values outside the range can't be found - assert(!std::binary_search(start, boost::prior(finish), *finish)); - - // Do the generic random_access_iterator_test - typedef typename CountingIterator::value_type value_type; - std::vector v; - for (value_type z = *start; z != *finish; ++z) - v.push_back(z); - if (v.size() >= 2) - { - // Note that this test requires a that the first argument is - // dereferenceable /and/ a valid iterator prior to the first argument - boost::random_access_iterator_test(start + 1, v.size() - 1, v.begin() + 1); - } -} - -// Special tests for bidirectional CountingIterators -template -void category_test(CountingIterator start, CountingIterator finish, std::bidirectional_iterator_tag) -{ - if (finish != start - && finish != boost::next(start) - && finish != boost::next(boost::next(start))) - { - // Note that this test requires a that the first argument is - // dereferenceable /and/ a valid iterator prior to the first argument - boost::bidirectional_iterator_test(boost::next(start), boost::next(*start), boost::next(boost::next(*start))); - } -} - -template -void category_test(CountingIterator start, CountingIterator finish, std::forward_iterator_tag) -{ - if (finish != start && finish != boost::next(start)) - boost::forward_iterator_test(start, *start, boost::next(*start)); -} - -template -void test_aux(CountingIterator start, CountingIterator finish) -{ - typedef typename CountingIterator::iterator_category category; - typedef typename CountingIterator::value_type value_type; - - // If it's a RandomAccessIterator we can do a few delicate tests - category_test(start, finish, category()); - - // Okay, brute force... - for (CountingIterator p = start; p != finish && boost::next(p) != finish; ++p) - { - assert(boost::next(*p) == *boost::next(p)); - } - - // prove that a reference can be formed to these values - typedef typename CountingIterator::value_type value; - const value* q = &*start; - (void)q; // suppress unused variable warning -} - -template -void test(Incrementable start, Incrementable finish) -{ - test_aux(boost::make_counting_iterator(start), boost::make_counting_iterator(finish)); -} - -template -void test_integer(Integer* = 0) // default arg works around MSVC bug -{ - Integer start = 0; - Integer finish = 120; - test(start, finish); -} - -template -void test_container(Container* = 0) // default arg works around MSVC bug -{ - Container c(1 + (unsigned)rand() % 1673); - - const typename Container::iterator start = c.begin(); - - // back off by 1 to leave room for dereferenceable value at the end - typename Container::iterator finish = start; - std::advance(finish, c.size() - 1); - - test(start, finish); - - typedef typename Container::const_iterator const_iterator; - test(const_iterator(start), const_iterator(finish)); -} - -class my_int1 { -public: - my_int1() { } - my_int1(int x) : m_int(x) { } - my_int1& operator++() { ++m_int; return *this; } - bool operator==(const my_int1& x) const { return m_int == x.m_int; } -private: - int m_int; -}; - -namespace boost { - template <> - struct counting_iterator_traits { - typedef std::ptrdiff_t difference_type; - typedef std::forward_iterator_tag iterator_category; - }; -} - -class my_int2 { -public: - typedef void value_type; - typedef void pointer; - typedef void reference; - typedef std::ptrdiff_t difference_type; - typedef std::bidirectional_iterator_tag iterator_category; - - my_int2() { } - my_int2(int x) : m_int(x) { } - my_int2& operator++() { ++m_int; return *this; } - my_int2& operator--() { --m_int; return *this; } - bool operator==(const my_int2& x) const { return m_int == x.m_int; } -private: - int m_int; -}; - -class my_int3 { -public: - typedef void value_type; - typedef void pointer; - typedef void reference; - typedef std::ptrdiff_t difference_type; - typedef std::random_access_iterator_tag iterator_category; - - my_int3() { } - my_int3(int x) : m_int(x) { } - my_int3& operator++() { ++m_int; return *this; } - my_int3& operator+=(std::ptrdiff_t n) { m_int += n; return *this; } - std::ptrdiff_t operator-(const my_int3& x) const { return m_int - x.m_int; } - my_int3& operator--() { --m_int; return *this; } - bool operator==(const my_int3& x) const { return m_int == x.m_int; } - bool operator!=(const my_int3& x) const { return m_int != x.m_int; } - bool operator<(const my_int3& x) const { return m_int < x.m_int; } -private: - int m_int; -}; - -int main() -{ - // Test the built-in integer types. - test_integer(); - test_integer(); - test_integer(); - test_integer(); - test_integer(); - test_integer(); - test_integer(); - test_integer(); - test_integer(); - test_integer(); -#if defined(ULLONG_MAX) || defined(ULONG_LONG_MAX) - test_integer(); - test_integer(); -#endif - - // wrapping an iterator or non-built-in integer type causes an INTERNAL - // COMPILER ERROR in MSVC without STLport. I'm clueless as to why. -#if !defined(BOOST_MSVC) || defined(__SGI_STL_PORT) - // Test user-defined type. - test_integer(); - test_integer(); - test_integer(); - - // Some tests on container iterators, to prove we handle a few different categories - test_container >(); - test_container >(); -# ifndef BOOST_NO_SLIST - test_container >(); -# endif - - // Also prove that we can handle raw pointers. - int array[2000]; - test(boost::make_counting_iterator(array), boost::make_counting_iterator(array+2000-1)); -#endif - std::cout << "test successful " << std::endl; - return 0; -} diff --git a/filter_iterator.htm b/filter_iterator.htm deleted file mode 100644 index fe5f10c..0000000 --- a/filter_iterator.htm +++ /dev/null @@ -1,273 +0,0 @@ - - - - - - -Filter Iterator Adaptor Documentation - - - - -c++boost.gif (8819 bytes) - -

Filter Iterator Adaptor

- -Defined in header -boost/iterator_adaptors.hpp - - -

-The filter iterator adaptor creates a view of an iterator range in -which some elements of the range are skipped over. A Predicate -function object controls which elements are skipped. When the -predicate is applied to an element, if it returns true then -the element is retained and if it returns false then the -element is skipped over. - - -

Synopsis

- -
-namespace boost {
-  template <class Predicate, class BaseIterator, ...>
-  class filter_iterator_generator;
-
-  template <class Predicate, class BaseIterator>
-  typename filter_iterator_generator<Predicate, BaseIterator>::type
-  make_filter_iterator(BaseIterator first, BaseIterator last, const Predicate& p = Predicate());
-}
-
- -
- -

The Filter Iterator Type -Generator

- -The class filter_iterator_generator is a helper class whose -purpose is to construct a filter iterator type. The template -parameters for this class are the Predicate function object -type and the BaseIterator type that is being wrapped. In -most cases the associated types for the wrapped iterator can be -deduced from std::iterator_traits, but in some situations the -user may want to override these types, so there are also template -parameters for each of the iterator's associated types. - -
-template <class Predicate, class BaseIterator,
-          class Value, class Reference, class Pointer, class Category, class Distance>
-class filter_iterator_generator
-{
-public:
-  typedef iterator_adaptor<...> type; // the resulting filter iterator type 
-}
-
- - -

Example

- -The following example uses filter iterator to print out all the -positive integers in an array. - -
-struct is_positive_number {
-  bool operator()(int x) { return 0 < x; }
-};
-int main() {
-  int numbers[] = { 0, -1, 4, -3, 5, 8, -2 };
-  const int N = sizeof(numbers)/sizeof(int);
-
-  typedef boost::filter_iterator_generator<is_positive_number, int*, int>::type FilterIter;
-  is_positive_number predicate;
-  FilterIter::policies_type policies(predicate, numbers + N);
-  FilterIter filter_iter_first(numbers, policies);
-  FilterIter filter_iter_last(numbers + N, policies);
-
-  std::copy(filter_iter_first, filter_iter_last, std::ostream_iterator<int>(std::cout, " "));
-  std::cout << std::endl;
-  return 0;
-}
-
-The output is: -
-4 5 8
-
- - -

Template Parameters

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ParameterDescription
PredicateThe function object that determines which elements are retained and which elements are skipped. -
BaseIteratorThe iterator type being wrapped. This type must at least be a model - of the InputIterator concept.
ValueThe value_type of the resulting iterator, -unless const. If const, a conforming compiler strips constness for the -value_type. Typically the default for this parameter is the -appropriate type[1].
Default: -std::iterator_traits<BaseIterator>::value_type
ReferenceThe reference type of the resulting iterator, and in -particular, the result type of operator*(). Typically the default for -this parameter is the appropriate type.
Default: If -Value is supplied, Value& is used. Otherwise -std::iterator_traits<BaseIterator>::reference is -used.
PointerThe pointer type of the resulting iterator, and in - particular, the result type of operator->(). - Typically the default for -this parameter is the appropriate type.
-Default: If Value was supplied, then Value*, -otherwise std::iterator_traits<BaseIterator>::pointer.
CategoryThe iterator_category type for the resulting iterator. -Typically the -default for this parameter is the appropriate type. If you override -this parameter, do not use bidirectional_iterator_tag -because filter iterators can not go in reverse.
-Default: std::iterator_traits<BaseIterator>::iterator_category
DistanceThe difference_type for the resulting iterator. Typically the default for -this parameter is the appropriate type.
-Default: std::iterator_traits<BaseIterator>::difference_type
- - -

Model of

- -The filter iterator adaptor (the type -filter_iterator_generator<...>::type) may be a model of InputIterator or ForwardIterator -depending on the adapted iterator type. - - -

Members

- -The filter iterator type implements all of the member functions and -operators required of the ForwardIterator -concept. In addition it has the following constructor: - -
filter_iterator_generator::type(const BaseIterator& it, const Policies& p = Policies())
- -

-The policies type has only one public function, which is its constructor: - -

filter_iterator_generator::policies_type(const Predicate& p, const BaseIterator& end)
- -

-


-

- -

The Make Filter Iterator Function

- -
-template <class Predicate, class BaseIterator>
-typename detail::filter_generator<Predicate, BaseIterator>::type
-make_filter_iterator(BaseIterator first, BaseIterator last, const Predicate& p = Predicate())
-
- -This function provides a convenient way to create filter iterators. - -

Example

- -In this example we print out all numbers in the array that are -greater than negative two. - -
-int main()
-{
-  int numbers[] = { 0, -1, 4, -3, 5, 8, -2 };
-  const int N = sizeof(numbers)/sizeof(int);
-
-  std::copy(boost::make_filter_iterator(numbers, numbers + N, 
-					std::bind2nd(std::greater(), -2)),
-	    boost::make_filter_iterator(numbers + N, numbers + N, 
-					std::bind2nd(std::greater(), -2)),
-	    std::ostream_iterator(std::cout, " "));
-  std::cout << std::endl;
-
-}
-
-The output is: -
-0 -1 4 5 8 
-
- -

-In the next example we print the positive numbers using the -make_filter_iterator() function. - -

-struct is_positive_number {
-  bool operator()(int x) { return 0 < x; }
-};
-int main()
-{
-  int numbers[] = { 0, -1, 4, -3, 5, 8, -2 };
-  const int N = sizeof(numbers)/sizeof(int);
-
-  std::copy(boost::make_filter_iterator<is_positive_number>(numbers, numbers + N),
-	    boost::make_filter_iterator<is_positive_number>(numbers + N, numbers + N),
-	    std::ostream_iterator<int>(std::cout, " "));
-  std::cout << std::endl;
-  return 0;
-}
-
-The output is: -
-4 5 8
-
- - -

Notes

- -[1] If the compiler does not support partial -specialization and the wrapped iterator type is a builtin pointer then -the Value type must be explicitly specified (don't use the -default). - - -
-

Revised 10 Feb 2001

-

© 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" -without express or implied warranty, and with no claim as to its suitability for -any purpose.

- - - - diff --git a/filter_iterator_example.cpp b/filter_iterator_example.cpp deleted file mode 100644 index 6ca0605..0000000 --- a/filter_iterator_example.cpp +++ /dev/null @@ -1,53 +0,0 @@ -// Example of using the filter iterator adaptor from -// boost/iterator_adaptors.hpp. - -// (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. - - -#include -#include -#include -#include -#include - -struct is_positive_number { - bool operator()(int x) { return 0 < x; } -}; - -int main() -{ - int numbers[] = { 0, -1, 4, -3, 5, 8, -2 }; - const int N = sizeof(numbers)/sizeof(int); - - // Example using make_filter_iterator() - std::copy(boost::make_filter_iterator(numbers, numbers + N), - boost::make_filter_iterator(numbers + N, numbers + N), - std::ostream_iterator(std::cout, " ")); - std::cout << std::endl; - - // Example using filter_iterator_generator - typedef boost::filter_iterator_generator::type - FilterIter; - is_positive_number predicate; - FilterIter::policies_type policies(predicate, numbers + N); - FilterIter filter_iter_first(numbers, policies); - FilterIter filter_iter_last(numbers + N, policies); - - std::copy(filter_iter_first, filter_iter_last, std::ostream_iterator(std::cout, " ")); - std::cout << std::endl; - - // Another example using make_filter_iterator() - std::copy(boost::make_filter_iterator(numbers, numbers + N, - std::bind2nd(std::greater(), -2)), - boost::make_filter_iterator(numbers + N, numbers + N, - std::bind2nd(std::greater(), -2)), - std::ostream_iterator(std::cout, " ")); - std::cout << std::endl; - - - return 0; -} diff --git a/half_open_range_test.cpp b/half_open_range_test.cpp deleted file mode 100644 index 04c2e97..0000000 --- a/half_open_range_test.cpp +++ /dev/null @@ -1,366 +0,0 @@ -// (C) Copyright David Abrahams 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 -// 11 Feb 2001 Compile with Borland, re-enable failing tests (David Abrahams) -// 29 Jan 2001 Initial revision (David Abrahams) - -#include -#include -#include -#include -#include -#include -#include -#include -#ifndef BOOST_NO_LIMITS -# include -#endif -#ifndef BOOST_NO_SLIST -# include -#endif - -inline unsigned unsigned_random(unsigned max) -{ - return (max > 0) ? (unsigned)rand() % max : 0; -} - -// Special tests for ranges supporting random access -template -void category_test_1( - const boost::half_open_range& r, std::random_access_iterator_tag) -{ - typedef boost::half_open_range range; - typedef typename range::size_type size_type; - size_type size = r.size(); - - // pick a random offset - size_type offset = unsigned_random(size); - - typename range::value_type x = *(r.begin() + offset); - // test contains(value_type) - assert(r.contains(r.start()) == !r.empty()); - assert(!r.contains(r.finish())); - assert(r.contains(x) == (offset != size)); - - range::const_iterator p = r.find(x); - assert((p == r.end()) == (x == r.finish())); - assert(r.find(r.finish()) == r.end()); - - if (offset != size) - { - assert(x == r[offset]); - assert(x == r.at(offset)); - } - - bool caught_out_of_range = false; - try { - bool never_initialized = x == r.at(size); - (void)never_initialized; - } - catch(std::out_of_range&) - { - caught_out_of_range = true; - } - catch(...) - { - } - assert(caught_out_of_range); -} - -// Those tests must be skipped for other ranges -template -void category_test_1( - const boost::half_open_range&, std::forward_iterator_tag) -{ -} - -unsigned indices[][2] = { {0,0},{0,1},{0,2},{0,3}, - {1,1},{1,2},{1,3}, - {2,2},{2,3}, - {3,3}}; - -template -void category_test_2( - const std::vector& ranges, unsigned i, unsigned j, std::random_access_iterator_tag) -{ - typedef Range range; - const range& ri = ranges[i]; - const range& rj = ranges[j]; - - if (indices[i][0] <= indices[j][0] && indices[i][1] >= indices[j][1]) - assert(ri.contains(rj)); - - if (ri.contains(rj)) - assert((ri & rj) == rj); - assert(boost::intersects(ri, rj) == !(ri & rj).empty()); - - range t1(ri); - t1 &= rj; - assert(t1 == range(indices[i][0] > indices[j][0] ? ri.start() : rj.start(), - indices[i][1] < indices[j][1] ? ri.finish() : rj.finish())); - assert(t1 == (ri & rj)); - - range t2(ri); - t2 |= rj; - - if (ri.empty()) - assert(t2 == rj); - else if (rj.empty()) - assert(t2 == ri); - else - assert(t2 == range(indices[i][0] < indices[j][0] ? ri.start() : rj.start(), - indices[i][1] > indices[j][1] ? ri.finish() : rj.finish())); - assert(t2 == (ri | rj)); - if (i == j) - assert(ri == rj); - - if (ri.empty() || rj.empty()) - assert((ri == rj) == (ri.empty() && rj.empty())); - else - assert((ri == rj) == (ri.start() == rj.start() && ri.finish() == rj.finish())); - - assert((ri == rj) == !(ri != rj)); - - bool same = ri == rj; - bool one_empty = ri.empty() != rj.empty(); - - std::less less; - std::less_equal less_equal; - std::greater greater; - std::greater_equal greater_equal; - - if (same) - { - assert(greater_equal(ri,rj)); - assert(less_equal(ri,rj)); - assert(!greater(ri,rj)); - assert(!less(ri,rj)); - } - else if (one_empty) - { - const range& empty = ri.empty() ? ri : rj; - const range& non_empty = rj.empty() ? ri : rj; - - assert(less(empty,non_empty)); - assert(less_equal(empty,non_empty)); - assert(!greater(empty,non_empty)); - assert(!greater_equal(empty,non_empty)); - assert(!less(non_empty,empty)); - assert(!less_equal(non_empty,empty)); - assert(greater(non_empty,empty)); - assert(greater_equal(non_empty,empty)); - } - else { - if (indices[i][0] < indices[j][0] || - indices[i][0] == indices[j][0] && indices[i][1] < indices[j][1]) - { - assert(!greater_equal(ri,rj)); - assert(less(ri,rj)); - } - - if (indices[i][0] < indices[j][0] || - indices[i][0] == indices[j][0] && indices[i][1] <= indices[j][1]) - { - assert(!greater(ri,rj)); - assert(less_equal(ri,rj)); - } - - if (indices[i][0] > indices[j][0] || - indices[i][0] == indices[j][0] && indices[i][1] > indices[j][1]) - { - assert(!less_equal(ri,rj)); - assert(greater(ri,rj)); - } - - if (indices[i][0] > indices[j][0] || - indices[i][0] == indices[j][0] && indices[i][1] >= indices[j][1]) - { - assert(!less(ri,rj)); - assert(greater_equal(ri,rj)); - } - } -} - - -template -void category_test_2( - const std::vector&, unsigned, unsigned, std::forward_iterator_tag) -{ -} - -template -void category_test_2( - const std::vector >&, unsigned, unsigned, std::bidirectional_iterator_tag) -{ -} - -template -void test_back(Range& x, std::bidirectional_iterator_tag) -{ - assert(x.back() == boost::prior(x.finish())); -} - -template -void test_back(Range& x, std::forward_iterator_tag) -{ -} - -template -boost::half_open_range range_identity(const boost::half_open_range& x) -{ - return x; -} - -template -void test(T x0, T x1, T x2, T x3) -{ - std::vector > ranges; - typedef boost::half_open_range range; - - T bounds[4] = { x0, x1, x2, x3 }; - - const std::size_t num_ranges = sizeof(indices)/sizeof(*indices); - // test construction - for (std::size_t n = 0; n < num_ranges;++n) - { - T start = bounds[indices[n][0]]; - T finish = bounds[indices[n][1]]; - boost::half_open_range r(start, finish); - ranges.push_back(r); - } - - // test implicit conversion from std::pair - range converted = std::pair(x0,x0); - (void)converted; - - // test assignment, equality and inequality - range r00 = range(x0, x0); - assert(r00 == range(x0,x0)); - assert(r00 == range(x1,x1)); // empty ranges are all equal - if (x3 != x0) - assert(r00 != range(x0, x3)); - r00 = range(x0, x3); - assert(r00 == range(x0, x3)); - if (x3 != x0) - assert(r00 != range(x0, x0)); - - typedef typename range::iterator iterator; - typedef typename iterator::iterator_category category; - - for (unsigned i = 0; i < num_ranges; ++i) - { - const range& r = ranges[i]; - - // test begin(), end(), basic iteration. - unsigned count = 0; - for (range::const_iterator p = r.begin(), finish = r.end(); - p != finish; - ++p, ++count) - { - assert(count < 2100); - } - - // test size(), empty(), front(), back() - assert((unsigned)r.size() == count); - if (indices[i][0] == indices[i][1]) - assert(r.empty()); - if (r.empty()) - assert(r.size() == 0); - if (!r.empty()) - { - assert(r.front() == r.start()); - test_back(r, category()); - } - - // test swap - range r1(r); - range r2(x0,x3); - const bool same = r1 == r2; - r1.swap(r2); - assert(r1 == range(x0,x3)); - assert(r2 == r); - if (!same) { - assert(r1 != r); - assert(r2 != range(x0,x3)); - } - - // do individual tests for random-access iterators - category_test_1(r, category()); - } - - for (unsigned j = 0; j < num_ranges; ++j) { - for (unsigned k = 0; k < num_ranges; ++k) { - category_test_2(ranges, j, k, category()); - } - } - -} - -template -void test_integer(Integer* = 0) // default arg works around MSVC bug -{ - Integer a = 0; - Integer b = a + unsigned_random(128 - a); - Integer c = b + unsigned_random(128 - b); - Integer d = c + unsigned_random(128 - c); - - test(a, b, c, d); -} - -template -void test_container(Container* = 0) // default arg works around MSVC bug -{ - Container c(unsigned_random(1673)); - - const typename Container::size_type offset1 = unsigned_random(c.size()); - const typename Container::size_type offset2 = unsigned_random(c.size() - offset1); - typename Container::iterator internal1 = c.begin(); - std::advance(internal1, offset1); - typename Container::iterator internal2 = internal1; - std::advance(internal2, offset2); - - test(c.begin(), internal1, internal2, c.end()); - - typedef typename Container::const_iterator const_iterator; - test(const_iterator(c.begin()), - const_iterator(internal1), - const_iterator(internal2), - const_iterator(c.end())); -} - -int main() -{ - // Test the built-in integer types. - test_integer(); - test_integer(); - test_integer(); - test_integer(); - test_integer(); - test_integer(); - test_integer(); - test_integer(); - test_integer(); - test_integer(); -#if defined(ULLONG_MAX) || defined(ULONG_LONG_MAX) - test_integer(); - test_integer(); -#endif - // Some tests on container iterators, to prove we handle a few different categories - test_container >(); - test_container >(); -#ifndef BOOST_NO_SLIST - test_container >(); -#endif - // Also prove that we can handle raw pointers. - int array[2000]; - const std::size_t a = 0; - const std::size_t b = a + unsigned_random(2000 - a); - const std::size_t c = b + unsigned_random(2000 - b); - test(array, array+b, array+c, array+2000); - return 0; -} diff --git a/include/boost/call_traits.hpp b/include/boost/call_traits.hpp deleted file mode 100644 index 345a440..0000000 --- a/include/boost/call_traits.hpp +++ /dev/null @@ -1,23 +0,0 @@ -// (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 -#endif - -#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -#include -#else -#include -#endif - -#endif // BOOST_CALL_TRAITS_HPP diff --git a/include/boost/compressed_pair.hpp b/include/boost/compressed_pair.hpp deleted file mode 100644 index c55ca2d..0000000 --- a/include/boost/compressed_pair.hpp +++ /dev/null @@ -1,23 +0,0 @@ -// (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 -#endif - -#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -#include -#else -#include -#endif - -#endif // BOOST_COMPRESSED_PAIR_HPP diff --git a/include/boost/detail/call_traits.hpp b/include/boost/detail/call_traits.hpp deleted file mode 100644 index ec161c6..0000000 --- a/include/boost/detail/call_traits.hpp +++ /dev/null @@ -1,141 +0,0 @@ -// (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 -#endif - -#ifndef BOOST_ARITHMETIC_TYPE_TRAITS_HPP -#include -#endif -#ifndef BOOST_COMPOSITE_TYPE_TRAITS_HPP -#include -#endif - -namespace boost{ - -namespace detail{ - -template -struct ct_imp -{ - typedef const T& param_type; -}; - -template -struct ct_imp -{ - typedef T const param_type; -}; - -template -struct ct_imp -{ - typedef T const param_type; -}; - -} - -template -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, - // however compiler bugs prevent this - instead pass three bool's to - // ct_imp and add an extra partial specialisation - // of ct_imp to handle the logic. (JM) - typedef typename detail::ct_imp::type>::value, ::boost::is_arithmetic::type>::value, sizeof(T) <= sizeof(void*)>::param_type param_type; -}; - -template -struct call_traits -{ - 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 -struct call_traits -{ - typedef T& value_type; - typedef T& reference; - typedef const T& const_reference; - typedef T& param_type; // hh removed const -}; -template -struct call_traits -{ - typedef T& value_type; - typedef T& reference; - typedef const T& const_reference; - typedef T& param_type; // hh removed const -}; -template -struct call_traits -{ - typedef T& value_type; - typedef T& reference; - typedef const T& const_reference; - typedef T& param_type; // hh removed const -}; -#endif - -template -struct call_traits -{ -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 -struct call_traits -{ -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 diff --git a/include/boost/detail/compressed_pair.hpp b/include/boost/detail/compressed_pair.hpp deleted file mode 100644 index 621a677..0000000 --- a/include/boost/detail/compressed_pair.hpp +++ /dev/null @@ -1,428 +0,0 @@ -// (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 -#ifndef BOOST_OBJECT_TYPE_TRAITS_HPP -#include -#endif -#ifndef BOOST_SAME_TRAITS_HPP -#include -#endif -#ifndef BOOST_CALL_TRAITS_HPP -#include -#endif - -namespace boost -{ - -// compressed_pair - -namespace details -{ - // JM altered 26 Jan 2000: - template - struct compressed_pair_switch; - - template - struct compressed_pair_switch - {static const int value = 0;}; - - template - struct compressed_pair_switch - {static const int value = 3;}; - - template - struct compressed_pair_switch - {static const int value = 1;}; - - template - struct compressed_pair_switch - {static const int value = 2;}; - - template - struct compressed_pair_switch - {static const int value = 4;}; - - template - struct compressed_pair_switch - {static const int value = 5;}; - - template 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 - inline void cp_swap(T& t1, T& t2) - { -#ifndef __GNUC__ - using std::swap; -#endif - swap(t1, t2); - } - - // 0 derive from neither - - template - class compressed_pair_imp - { - public: - typedef T1 first_type; - typedef T2 second_type; - typedef typename call_traits::param_type first_param_type; - typedef typename call_traits::param_type second_param_type; - typedef typename call_traits::reference first_reference; - typedef typename call_traits::reference second_reference; - typedef typename call_traits::const_reference first_const_reference; - typedef typename call_traits::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 compressed_pair_imp - : private T1 - { - public: - typedef T1 first_type; - typedef T2 second_type; - typedef typename call_traits::param_type first_param_type; - typedef typename call_traits::param_type second_param_type; - typedef typename call_traits::reference first_reference; - typedef typename call_traits::reference second_reference; - typedef typename call_traits::const_reference first_const_reference; - typedef typename call_traits::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 compressed_pair_imp - : private T2 - { - public: - typedef T1 first_type; - typedef T2 second_type; - typedef typename call_traits::param_type first_param_type; - typedef typename call_traits::param_type second_param_type; - typedef typename call_traits::reference first_reference; - typedef typename call_traits::reference second_reference; - typedef typename call_traits::const_reference first_const_reference; - typedef typename call_traits::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 compressed_pair_imp - : private T1, - private T2 - { - public: - typedef T1 first_type; - typedef T2 second_type; - typedef typename call_traits::param_type first_param_type; - typedef typename call_traits::param_type second_param_type; - typedef typename call_traits::reference first_reference; - typedef typename call_traits::reference second_reference; - typedef typename call_traits::const_reference first_const_reference; - typedef typename call_traits::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 compressed_pair_imp - : private T1 - { - public: - typedef T1 first_type; - typedef T2 second_type; - typedef typename call_traits::param_type first_param_type; - typedef typename call_traits::param_type second_param_type; - typedef typename call_traits::reference first_reference; - typedef typename call_traits::reference second_reference; - typedef typename call_traits::const_reference first_const_reference; - typedef typename call_traits::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 compressed_pair_imp - { - public: - typedef T1 first_type; - typedef T2 second_type; - typedef typename call_traits::param_type first_param_type; - typedef typename call_traits::param_type second_param_type; - typedef typename call_traits::reference first_reference; - typedef typename call_traits::reference second_reference; - typedef typename call_traits::const_reference first_const_reference; - typedef typename call_traits::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& y) - { - cp_swap(first_, y.first_); - cp_swap(second_, y.second_); - } - private: - first_type first_; - second_type second_; - }; - -} // details - -template -class compressed_pair - : private ::boost::details::compressed_pair_imp::type, typename remove_cv::type>::value, - ::boost::is_empty::value, - ::boost::is_empty::value>::value> -{ -private: - typedef details::compressed_pair_imp::type, typename remove_cv::type>::value, - ::boost::is_empty::value, - ::boost::is_empty::value>::value> base; -public: - typedef T1 first_type; - typedef T2 second_type; - typedef typename call_traits::param_type first_param_type; - typedef typename call_traits::param_type second_param_type; - typedef typename call_traits::reference first_reference; - typedef typename call_traits::reference second_reference; - typedef typename call_traits::const_reference first_const_reference; - typedef typename call_traits::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 compressed_pair - : private details::compressed_pair_imp::type, typename remove_cv::type>::value, - ::boost::is_empty::value, - ::boost::is_empty::value>::value> -{ -private: - typedef details::compressed_pair_imp::type, typename remove_cv::type>::value, - ::boost::is_empty::value, - ::boost::is_empty::value>::value> base; -public: - typedef T first_type; - typedef T second_type; - typedef typename call_traits::param_type first_param_type; - typedef typename call_traits::param_type second_param_type; - typedef typename call_traits::reference first_reference; - typedef typename call_traits::reference second_reference; - typedef typename call_traits::const_reference first_const_reference; - typedef typename call_traits::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 -inline -void -swap(compressed_pair& x, compressed_pair& y) -{ - x.swap(y); -} - -} // boost - -#endif // BOOST_DETAIL_COMPRESSED_PAIR_HPP - - - diff --git a/include/boost/detail/ob_call_traits.hpp b/include/boost/detail/ob_call_traits.hpp deleted file mode 100644 index 091eea3..0000000 --- a/include/boost/detail/ob_call_traits.hpp +++ /dev/null @@ -1,128 +0,0 @@ -// (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 -#endif - -#ifndef BOOST_ARITHMETIC_TYPE_TRAITS_HPP -#include -#endif -#ifndef BOOST_COMPOSITE_TYPE_TRAITS_HPP -#include -#endif - -namespace boost{ - -#if defined(BOOST_MSVC6_MEMBER_TEMPLATES) || !defined(BOOST_NO_MEMBER_TEMPLATES) -// -// use member templates to emulate -// partial specialisation: -// -namespace detail{ - -template -struct standard_call_traits -{ - typedef T value_type; - typedef T& reference; - typedef const T& const_reference; - typedef const T& param_type; -}; -template -struct simple_call_traits -{ - typedef T value_type; - typedef T& reference; - typedef const T& const_reference; - typedef const T param_type; -}; -template -struct reference_call_traits -{ - typedef T value_type; - typedef T reference; - typedef T const_reference; - typedef T param_type; -}; -template -struct call_traits_chooser -{ - template - struct rebind - { - typedef standard_call_traits type; - }; -}; -template <> -struct call_traits_chooser -{ - template - struct rebind - { - typedef simple_call_traits type; - }; -}; -template <> -struct call_traits_chooser -{ - template - struct rebind - { - typedef reference_call_traits type; - }; -}; -} // namespace detail -template -struct call_traits -{ -private: - typedef detail::call_traits_chooser<(is_pointer::value || is_arithmetic::value) && sizeof(T) <= sizeof(void*), is_reference::value> chooser; - typedef typename chooser::template rebind 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 -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 diff --git a/include/boost/detail/ob_compressed_pair.hpp b/include/boost/detail/ob_compressed_pair.hpp deleted file mode 100644 index c8293ec..0000000 --- a/include/boost/detail/ob_compressed_pair.hpp +++ /dev/null @@ -1,509 +0,0 @@ -// (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 -#ifndef BOOST_OBJECT_TYPE_TRAITS_HPP -#include -#endif -#ifndef BOOST_SAME_TRAITS_HPP -#include -#endif -#ifndef BOOST_CALL_TRAITS_HPP -#include -#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 compressed_pair; - -namespace detail{ - -template -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 -struct init_one; - -template <> -struct init_one<1> -{ - template - static void init(const A& a, T1* p1, T2*) - { - *p1 = a; - } -}; - -template <> -struct init_one<2> -{ - template - static void init(const A& a, T1*, T2* p2) - { - *p2 = a; - } -}; - - -// T1 != T2, both non-empty -template -class compressed_pair_0 -{ -private: - T1 _first; - T2 _second; -public: - typedef T1 first_type; - typedef T2 second_type; - typedef typename call_traits::param_type first_param_type; - typedef typename call_traits::param_type second_param_type; - typedef typename call_traits::reference first_reference; - typedef typename call_traits::reference second_reference; - typedef typename call_traits::const_reference first_const_reference; - typedef typename call_traits::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 - explicit compressed_pair_0(const A& val) - { - init_one::value>::init(val, &_first, &_second); - } - compressed_pair_0(const ::boost::compressed_pair& 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 compressed_pair_1 : T2 -{ -private: - T1 _first; -public: - typedef T1 first_type; - typedef T2 second_type; - typedef typename call_traits::param_type first_param_type; - typedef typename call_traits::param_type second_param_type; - typedef typename call_traits::reference first_reference; - typedef typename call_traits::reference second_reference; - typedef typename call_traits::const_reference first_const_reference; - typedef typename call_traits::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 - explicit compressed_pair_1(const A& val) - { - init_one::value>::init(val, &_first, static_cast(this)); - } - - compressed_pair_1(const ::boost::compressed_pair& 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 compressed_pair_2 : T1 -{ -private: - T2 _second; -public: - typedef T1 first_type; - typedef T2 second_type; - typedef typename call_traits::param_type first_param_type; - typedef typename call_traits::param_type second_param_type; - typedef typename call_traits::reference first_reference; - typedef typename call_traits::reference second_reference; - typedef typename call_traits::const_reference first_const_reference; - typedef typename call_traits::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 - explicit compressed_pair_2(const A& val) - { - init_one::value>::init(val, static_cast(this), &_second); - } - compressed_pair_2(const ::boost::compressed_pair& 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 compressed_pair_3 : T1, T2 -{ -public: - typedef T1 first_type; - typedef T2 second_type; - typedef typename call_traits::param_type first_param_type; - typedef typename call_traits::param_type second_param_type; - typedef typename call_traits::reference first_reference; - typedef typename call_traits::reference second_reference; - typedef typename call_traits::const_reference first_const_reference; - typedef typename call_traits::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 - explicit compressed_pair_3(const A& val) - { - init_one::value>::init(val, static_cast(this), static_cast(this)); - } - compressed_pair_3(const ::boost::compressed_pair& 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 compressed_pair_4 : T1 -{ -public: - typedef T1 first_type; - typedef T2 second_type; - typedef typename call_traits::param_type first_param_type; - typedef typename call_traits::param_type second_param_type; - typedef typename call_traits::reference first_reference; - typedef typename call_traits::reference second_reference; - typedef typename call_traits::const_reference first_const_reference; - typedef typename call_traits::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& 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 compressed_pair_5 -{ -private: - T1 _first; - T2 _second; -public: - typedef T1 first_type; - typedef T2 second_type; - typedef typename call_traits::param_type first_param_type; - typedef typename call_traits::param_type second_param_type; - typedef typename call_traits::reference first_reference; - typedef typename call_traits::reference second_reference; - typedef typename call_traits::const_reference first_const_reference; - typedef typename call_traits::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& 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 -struct compressed_pair_chooser -{ - template - struct rebind - { - typedef compressed_pair_0 type; - }; -}; - -template <> -struct compressed_pair_chooser -{ - template - struct rebind - { - typedef compressed_pair_1 type; - }; -}; - -template <> -struct compressed_pair_chooser -{ - template - struct rebind - { - typedef compressed_pair_2 type; - }; -}; - -template <> -struct compressed_pair_chooser -{ - template - struct rebind - { - typedef compressed_pair_3 type; - }; -}; - -template <> -struct compressed_pair_chooser -{ - template - struct rebind - { - typedef compressed_pair_4 type; - }; -}; - -template <> -struct compressed_pair_chooser -{ - template - struct rebind - { - typedef compressed_pair_5 type; - }; -}; - -template -struct compressed_pair_traits -{ -private: - typedef compressed_pair_chooser::value, is_empty::value, is_same::value> chooser; - typedef typename chooser::template rebind bound_type; -public: - typedef typename bound_type::type type; -}; - -} // namespace detail - -template -class compressed_pair : public detail::compressed_pair_traits::type -{ -private: - typedef typename detail::compressed_pair_traits::type base_type; -public: - typedef T1 first_type; - typedef T2 second_type; - typedef typename call_traits::param_type first_param_type; - typedef typename call_traits::param_type second_param_type; - typedef typename call_traits::reference first_reference; - typedef typename call_traits::reference second_reference; - typedef typename call_traits::const_reference first_const_reference; - typedef typename call_traits::const_reference second_const_reference; - - compressed_pair() : base_type() {} - compressed_pair(first_param_type x, second_param_type y) : base_type(x, y) {} - template - 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 -inline void swap(compressed_pair& x, compressed_pair& y) -{ - x.swap(y); -} - -#else -// no partial specialisation, no member templates: - -template -class compressed_pair -{ -private: - T1 _first; - T2 _second; -public: - typedef T1 first_type; - typedef T2 second_type; - typedef typename call_traits::param_type first_param_type; - typedef typename call_traits::param_type second_param_type; - typedef typename call_traits::reference first_reference; - typedef typename call_traits::reference second_reference; - typedef typename call_traits::const_reference first_const_reference; - typedef typename call_traits::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 -inline void swap(compressed_pair& x, compressed_pair& y) -{ - x.swap(y); -} - -#endif - -} // boost - -#endif // BOOST_OB_COMPRESSED_PAIR_HPP - - - diff --git a/include/boost/operators.hpp b/include/boost/operators.hpp deleted file mode 100644 index e6a2cb0..0000000 --- a/include/boost/operators.hpp +++ /dev/null @@ -1,565 +0,0 @@ -// Boost operators.hpp header file ----------------------------------------// - -// (C) Copyright David Abrahams 1999. Permission to copy, use, -// modify, sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -// (C) Copyright Jeremy Siek 1999. Permission to copy, use, modify, -// sell and distribute this software is granted provided this -// copyright notice appears in all copies. This software is provided -// "as is" without express or implied warranty, and with no claim as -// to its suitability for any purpose. - -// See http://www.boost.org for most recent version including documentation. - -// Revision History -// 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 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 -#include - -#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 -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 -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 -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 -struct equality_comparable1 : B -{ - friend bool operator!=(const T& x, const T& y) { return !(x == y); } -}; - -template -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 -struct multipliable1 : B -{ - friend T operator*(T x, const T& y) { return x *= y; } -}; - -template -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 -struct addable1 : B -{ - friend T operator+(T x, const T& y) { return x += y; } -}; - -template -struct subtractable2 : B -{ - friend T operator-(T x, const U& y) { return x -= y; } -}; - -template -struct subtractable1 : B -{ - friend T operator-(T x, const T& y) { return x -= y; } -}; - -template -struct dividable2 : B -{ - friend T operator/(T x, const U& y) { return x /= y; } -}; - -template -struct dividable1 : B -{ - friend T operator/(T x, const T& y) { return x /= y; } -}; - -template -struct modable2 : B -{ - friend T operator%(T x, const U& y) { return x %= y; } -}; - -template -struct modable1 : B -{ - friend T operator%(T x, const T& y) { return x %= y; } -}; - -template -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 -struct xorable1 : B -{ - friend T operator^(T x, const T& y) { return x ^= y; } -}; - -template -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 -struct andable1 : B -{ - friend T operator&(T x, const T& y) { return x &= y; } -}; - -template -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 -struct orable1 : B -{ - friend T operator|(T x, const T& y) { return x |= y; } -}; - -// incrementable and decrementable contributed by Jeremy Siek - -template -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 -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 -struct dereferenceable : B -{ - P operator->() const - { - return &*static_cast(*this); - } -}; - -template -struct indexable : B -{ - R operator[](I n) const - { - return *(static_cast(*this) + n); - } -}; - -#ifndef BOOST_NO_OPERATORS_IN_NAMESPACE -} // namespace boost -#endif // BOOST_NO_OPERATORS_IN_NAMESPACE - - -// BOOST_IMPORT_TEMPLATE1/BOOST_IMPORT_TEMPLATE2 - -// -// When BOOST_NO_OPERATORS_IN_NAMESPACE is defined we need a way to import an -// operator template into the boost namespace. BOOST_IMPORT_TEMPLATE1 is used -// 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. - -#if defined(BOOST_NO_OPERATORS_IN_NAMESPACE) - -# if defined(BOOST_NO_USING_TEMPLATE) - - // Because a Borland C++ 5.5 bug prevents a using declaration from working, - // we are forced to use inheritance for that compiler. -# define BOOST_IMPORT_TEMPLATE2(template_name) \ - template \ - struct template_name : ::template_name {}; - -# define BOOST_IMPORT_TEMPLATE1(template_name) \ - template \ - struct template_name : ::template_name {}; - -# else - - // Otherwise, bring the names in with a using-declaration to avoid - // stressing the compiler -# define BOOST_IMPORT_TEMPLATE2(template_name) using ::template_name; -# define BOOST_IMPORT_TEMPLATE1(template_name) using ::template_name; - -# endif // BOOST_NO_USING_TEMPLATE - -#else // !BOOST_NO_OPERATORS_IN_NAMESPACE - - // The template is already in boost so we have nothing to do. -# define BOOST_IMPORT_TEMPLATE2(template_name) -# define BOOST_IMPORT_TEMPLATE1(template_name) - -#endif // BOOST_NO_OPERATORS_IN_NAMESPACE - -// -// 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. -// -#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) - -// is_chained_base<> - a traits class used to distinguish whether an operator -// template argument is being used for base class chaining, or is specifying a -// 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 struct is_chained_base { - typedef ::boost::detail::false_t value; -}; - -} // namespace boost - -// 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 \ - struct is_chained_base< ::boost::template_name2 > { \ - 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 \ - struct is_chained_base< ::boost::template_name1 > { \ - 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 '1' -// and '2' which must implement the corresponding 1- and 2- -// argument forms. -// -// The template type parameter O == is_chained_base::value is used to -// distinguish whether the 2nd argument to 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 '1' or '2'. -// - -# define BOOST_OPERATOR_TEMPLATE(template_name) \ -template ::value \ - > \ -struct template_name : template_name##2 {}; \ - \ -template \ -struct template_name \ - : template_name##1 {}; \ - \ -template \ -struct template_name \ - : template_name##1 {}; \ - \ -template \ -struct is_chained_base< ::boost::template_name > { \ - 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_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 \ - struct template_name : template_name##1 {}; - -#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) - -// indexable doesn't follow the patterns above (it has 4 template arguments), so -// we just write out the compiler hacks explicitly. -#ifdef BOOST_NO_OPERATORS_IN_NAMESPACE -# ifdef BOOST_NO_USING_TEMPLATE - template - struct indexable : ::indexable {}; -# else - using ::indexable; -# endif -#endif - -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -template -struct is_chained_base< ::boost::indexable > { - typedef ::boost::detail::true_t operator_template_type; -}; -#endif - -#undef BOOST_OPERATOR_TEMPLATE -#undef BOOST_OPERATOR_TEMPLATE2 -#undef BOOST_OPERATOR_TEMPLATE1 -#undef BOOST_IMPORT_TEMPLATE1 -#undef BOOST_IMPORT_TEMPLATE2 - -// The following 'operators' classes can only be used portably if the derived class -// declares ALL of the required member operators. -template -struct operators2 - : less_than_comparable2 > > > > > > > > > {}; - -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION -template -struct operators : operators2 {}; - -template struct operators -#else -template struct operators -#endif - : less_than_comparable > > > > > > > > > > > {}; - -// Iterator helper classes (contributed by Jeremy Siek) -------------------// -template -struct forward_iterator_helper - : equality_comparable > > > {}; - -template -struct bidirectional_iterator_helper - : equality_comparable > > > > {}; - -template -struct random_access_iterator_helper - : equality_comparable > > > > > > > > -{ -#ifndef __BORLANDC__ - friend D requires_difference_operator(const T& x, const T& y) { - return x - y; - } -#endif -}; // random_access_iterator_helper - -} // namespace boost - -#if defined(__sgi) && !defined(__GNUC__) -#pragma reset woff 1234 -#endif - -#endif // BOOST_OPERATORS_HPP diff --git a/include/boost/utility.hpp b/include/boost/utility.hpp deleted file mode 100644 index 82a7d13..0000000 --- a/include/boost/utility.hpp +++ /dev/null @@ -1,96 +0,0 @@ -// 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 -// 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 -#include // for size_t -#include // for std::pair - -namespace boost -{ - -// next() and prior() template functions -----------------------------------// - - // Helper functions for classes like bidirectional iterators not supporting - // operator+ and operator-. - // - // Usage: - // const std::list::iterator p = get_some_iterator(); - // const std::list::iterator prev = boost::prior(p); - - // Contributed by Dave Abrahams - - template - T next(T x) { return ++x; } - - template - 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 tied { - public: - inline tied(A& a, B& b) : _a(a), _b(b) { } - template - inline tied& operator=(const std::pair& p) { - _a = p.first; - _b = p.second; - return *this; - } - protected: - A& _a; - B& _b; - }; - - template - inline tied tie(A& a, B& b) { return tied(a, b); } - -} // namespace boost - -#endif // BOOST_UTILITY_HPP - diff --git a/indirect_iterator.htm b/indirect_iterator.htm deleted file mode 100644 index 394e8f8..0000000 --- a/indirect_iterator.htm +++ /dev/null @@ -1,444 +0,0 @@ - - - - - - - - - - Indirect Iterator Adaptor Documentation - - - - - c++boost.gif (8819 bytes) - -

Indirect Iterator Adaptor

- Defined in header boost/iterator_adaptors.hpp - -

The indirect iterator adaptor augments an iterator by applying an - extra dereference inside of operator*(). For example, this - iterator makes it possible to view a container of pointers or - smart-pointers (e.g. std::list<boost::shared_ptr<foo> - >) as if it were a container of the pointed-to type. The following - pseudo-code shows the basic idea of the indirect iterator: - -

-
-// inside a hypothetical indirect_iterator class...
-typedef std::iterator_traits<BaseIterator>::value_type Pointer;
-typedef std::iterator_traits<Pointer>::reference reference;
-
-reference indirect_iterator::operator*() const {
-  return **this->base_iterator;
-}
-
-
- -

Synopsis

- -
-
-namespace boost {
-  template <class BaseIterator,
-            class Value, class Reference, class Category, class Pointer>
-  struct indirect_iterator_generator;
-  
-  template <class BaseIterator,
-            class Value, class Reference, class ConstReference, 
-            class Category, class Pointer, class ConstPointer>
-  struct indirect_iterator_pair_generator;
-
-  template <class BaseIterator>
-  typename indirect_iterator_generator<BaseIterator>::type
-  make_indirect_iterator(BaseIterator base)  
-}
-
-
-
- -

The Indirect Iterator Type - Generator

- The indirect_iterator_generator template is a generator of - indirect iterator types. The main template parameter for this class is the - BaseIterator type that is being wrapped. In most cases the type of - the elements being pointed to can be deduced using - std::iterator_traits, but in some situations the user may want to - override this type, so there are also template parameters that allow a user - to control the value_type, pointer, and - reference types of the resulting iterators. - -
-
-template <class BaseIterator,
-          class Value, class Reference, class Pointer>
-class indirect_iterator_generator
-{
-public:
-  typedef iterator_adaptor<...> type; // the resulting indirect iterator type 
-};
-
-
- -

Example

- This example uses the indirect_iterator_generator to create - indirect iterators which dereference the pointers stored in the - pointers_to_chars array to access the chars in the - characters array. - -
-
-#include <boost/config.hpp>
-#include <vector>
-#include <iostream>
-#include <iterator>
-#include <boost/iterator_adaptors.hpp>
-
-int main(int, char*[])
-{
-  char characters[] = "abcdefg";
-  const int N = sizeof(characters)/sizeof(char) - 1; // -1 since characters has a null char
-  char* pointers_to_chars[N];                        // at the end.
-  for (int i = 0; i < N; ++i)
-    pointers_to_chars[i] = &characters[i];
-  
-  boost::indirect_iterator_generator<char**, char>::type 
-    indirect_first(pointers_to_chars), indirect_last(pointers_to_chars + N);
-
-  std::copy(indirect_first, indirect_last, std::ostream_iterator<char>(std::cout, ","));
-  std::cout << std::endl;
-  
-  // to be continued...
-
-
- -

Template Parameters

- - - - - - - - -
Parameter - - Description - -
BaseIterator - - The iterator type being wrapped. The value_type - of the base iterator should itself be dereferenceable. - The return type of the operator* for the - value_type should match the Reference type. - -
Value - - The value_type of the resulting iterator, unless const. If - Value is const X, a conforming compiler makes the - value_type non-const X[1]. Note that if the default - is used for Value, then there must be a valid specialization - of iterator_traits for the value type of the base iterator. -
- Default: std::iterator_traits<
-   std::iterator_traits<BaseIterator>::value_type - >::value_type
[2] - -
Reference - - The reference type of the resulting iterator, and in - particular, the result type of operator*().
- Default: Value& - -
Pointer - - The pointer type of the resulting iterator, and in - particular, the result type of operator->().
- Default: Value* - -
Category - The iterator_category type for the resulting iterator.
- Default: - std::iterator_traits<BaseIterator>::iterator_category - -
- -

Concept Model

- The indirect iterator will model whichever standard iterator - concept category is modeled by the base iterator. Thus, if the - base iterator is a model of Random - Access Iterator then so is the resulting indirect iterator. If - the base iterator models a more restrictive concept, the resulting - indirect iterator will model the same concept [3]. - -

Members

- The indirect iterator type implements the member functions and operators - required of the Random Access - Iterator concept. In addition it has the following constructor: -
-explicit indirect_iterator_generator::type(const BaseIterator& it)
-
-
-
- -
- -

- -

The Indirect Iterator Pair - Generator

- Sometimes a pair of const/non-const pair of iterators is - needed, such as when implementing a container. The - indirect_iterator_pair_generator class makes it more convenient to - create this pair of iterator types. - -
-
-template <class BaseIterator,
-          class Value, class Pointer, class Reference,
-          class ConstPointer, class ConstReference>
-class indirect_iterator_pair_generator
-{
-public:
-  typedef iterator_adaptor<...> iterator;       // the mutable indirect iterator type 
-  typedef iterator_adaptor<...> const_iterator; // the immutable indirect iterator type 
-};
-
-
- -

Example

- -
-
-  // continuing from the last example...
-
-  typedef boost::indirect_iterator_pair_generator<char**,
-    char, char*, char&, const char*, const char&> PairGen;
-
-  char mutable_characters[N];
-  char* pointers_to_mutable_chars[N];
-  for (int i = 0; i < N; ++i)
-    pointers_to_mutable_chars[i] = &mutable_characters[i];
-
-  PairGen::iterator mutable_indirect_first(pointers_to_mutable_chars),
-    mutable_indirect_last(pointers_to_mutable_chars + N);
-  PairGen::const_iterator const_indirect_first(pointers_to_chars),
-    const_indirect_last(pointers_to_chars + N);
-
-  std::transform(const_indirect_first, const_indirect_last,
-     mutable_indirect_first, std::bind1st(std::plus<char>(), 1));
-
-  std::copy(mutable_indirect_first, mutable_indirect_last,
-      std::ostream_iterator<char>(std::cout, ","));
-  std::cout << std::endl;
-  // to be continued...
-
-
- -

The output is: - -

-
-b,c,d,e,f,g,h,
-
-
- -

Template Parameters

- - - - - - - - - - -
Parameter - - Description - -
BaseIterator - - The iterator type being wrapped. The value_type of the - base iterator should itself be dereferenceable. - The return type of the operator* for the - value_type should match the Reference type. - -
Value - - The value_type of the resulting iterators. - If Value is const X, a conforming compiler makes the - value_type non-const X[1]. Note that if the default - is used for Value, then there must be a valid - specialization of iterator_traits for the value type - of the base iterator.
- - Default: std::iterator_traits<
-   std::iterator_traits<BaseIterator>::value_type - >::value_type
[2] - -
Reference - - The reference type of the resulting iterator, and - in particular, the result type of its operator*().
- Default: Value& - -
Pointer - - The pointer type of the resulting iterator, and - in particular, the result type of its operator->().
- Default: Value* - -
ConstReference - - The reference type of the resulting - const_iterator, and in particular, the result type of its - operator*().
- Default: const Value& - -
ConstPointer - - The pointer type of the resulting const_iterator, - and in particular, the result type of its operator->().
- Default: const Value* - -
Category - The iterator_category type for the resulting iterator.
- Default: - std::iterator_traits<BaseIterator>::iterator_category -
- -

Concept Model

- - The indirect iterators will model whichever standard iterator - concept category is modeled by the base iterator. Thus, if the - base iterator is a model of Random - Access Iterator then so are the resulting indirect - iterators. If the base iterator models a more restrictive concept, - the resulting indirect iterators will model the same concept [3]. - - -

Members

- The resulting iterator and const_iterator types implement - the member functions and operators required of the Random Access - Iterator concept. In addition they support the following constructors: - -
-
-explicit indirect_iterator_pair_generator::iterator(const BaseIterator& it)
-explicit indirect_iterator_pair_generator::const_iterator(const BaseIterator& it)
-
-
-
-
- -
- -

- -

The Indirect Iterator Object - Generator

- The make_indirect_iterator() function provides a more convenient - way to create indirect iterator objects. The function saves the user the - trouble of explicitly writing out the iterator types. - -
-
-template <class BaseIterator>
-typename indirect_iterator_generator<BaseIterator>::type
-make_indirect_iterator(BaseIterator base)  
-
-
- -

Example

- Here we again print the chars from the array characters - by accessing them through the array of pointers pointer_to_chars, - but this time we use the make_indirect_iterator() function which - saves us some typing. - -
-
-  // continuing from the last example...
-
-  std::copy(boost::make_indirect_iterator(pointers_to_chars), 
-      boost::make_indirect_iterator(pointers_to_chars + N),
-      std::ostream_iterator<char>(std::cout, ","));
-  std::cout << std::endl;
-
-  return 0;
-}
-
-
- The output is: - -
-
-a,b,c,d,e,f,g,
-
-
-
- -

Notes

- -

- -

[2] If your compiler does not support partial - specialization and the base iterator or its value_type is a - builtin pointer type, you will not be able to use the default for - Value and will need to specify this type explicitly. - -

[3]There is a caveat to which concept the - indirect iterator can model. If the return type of the - operator* for the base iterator's value type is not a - true reference, then strickly speaking, the indirect iterator can - not be a model of Forward - Iterator or any of the concepts that refine it. In this case - the Category for the indirect iterator should be - specified as std::input_iterator_tag. However, even in - this case, if the base iterator is a random access iterator, the - resulting indirect iterator will still satisfy most of the - requirements for Random - Access Iterator. - -


- -

Revised - 10 - Feb 2001 - - -

© Copyright Jeremy Siek and David Abrahams 2001. 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" without express or implied warranty, and with no claim as to its - suitability for any purpose. - - - - - - - - diff --git a/indirect_iterator_example.cpp b/indirect_iterator_example.cpp deleted file mode 100644 index 8f1d389..0000000 --- a/indirect_iterator_example.cpp +++ /dev/null @@ -1,61 +0,0 @@ -// (C) Copyright Jeremy Siek 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. - -#include -#include -#include -#include -#include -#include - -int main(int, char*[]) -{ - char characters[] = "abcdefg"; - const int N = sizeof(characters)/sizeof(char) - 1; // -1 since characters has a null char - char* pointers_to_chars[N]; // at the end. - for (int i = 0; i < N; ++i) - pointers_to_chars[i] = &characters[i]; - - // Example of using indirect_iterator_generator - - boost::indirect_iterator_generator::type - indirect_first(pointers_to_chars), indirect_last(pointers_to_chars + N); - - std::copy(indirect_first, indirect_last, std::ostream_iterator(std::cout, ",")); - std::cout << std::endl; - - - // Example of using indirect_iterator_pair_generator - - typedef boost::indirect_iterator_pair_generator PairGen; - - char mutable_characters[N]; - char* pointers_to_mutable_chars[N]; - for (int i = 0; i < N; ++i) - pointers_to_mutable_chars[i] = &mutable_characters[i]; - - PairGen::iterator mutable_indirect_first(pointers_to_mutable_chars), - mutable_indirect_last(pointers_to_mutable_chars + N); - PairGen::const_iterator const_indirect_first(pointers_to_chars), - const_indirect_last(pointers_to_chars + N); - - std::transform(const_indirect_first, const_indirect_last, - mutable_indirect_first, std::bind1st(std::plus(), 1)); - - std::copy(mutable_indirect_first, mutable_indirect_last, - std::ostream_iterator(std::cout, ",")); - std::cout << std::endl; - - - // Example of using make_indirect_iterator() - - std::copy(boost::make_indirect_iterator(pointers_to_chars), - boost::make_indirect_iterator(pointers_to_chars + N), - std::ostream_iterator(std::cout, ",")); - std::cout << std::endl; - - return 0; -} diff --git a/iter_adaptor_fail_expected1.cpp b/iter_adaptor_fail_expected1.cpp deleted file mode 100644 index 2d0288c..0000000 --- a/iter_adaptor_fail_expected1.cpp +++ /dev/null @@ -1,27 +0,0 @@ -// Test boost/pending/iterator_adaptors.hpp - -// (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 -// 21 Jan 01 Initial version (Jeremy Siek) - -#include -#include -#include - -int main() -{ - typedef boost::iterator_adaptor::iterator, - boost::default_iterator_policies, - int,int&,int*,std::bidirectional_iterator_tag> adaptor_type; - - adaptor_type i; - i += 4; - return 0; -} diff --git a/iter_adaptor_fail_expected2.cpp b/iter_adaptor_fail_expected2.cpp deleted file mode 100644 index 592801d..0000000 --- a/iter_adaptor_fail_expected2.cpp +++ /dev/null @@ -1,28 +0,0 @@ -// Test boost/pending/iterator_adaptors.hpp - -// (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 -// 21 Jan 01 Initial version (Jeremy Siek) - -#include -#include -#include -#include - -int main() -{ - typedef boost::iterator_adaptor, - boost::default_iterator_policies, - int,int&,int*,std::input_iterator_tag> adaptor_type; - - adaptor_type iter; - --iter; - return 0; -} diff --git a/iterator_adaptor_examples.cpp b/iterator_adaptor_examples.cpp deleted file mode 100644 index c7baa08..0000000 --- a/iterator_adaptor_examples.cpp +++ /dev/null @@ -1,47 +0,0 @@ -// (C) Copyright Jeremy Siek 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. - - -#include -#include -#include -#include -#include - -int -main(int, char*[]) -{ - // This is a simple example of using the transform_iterators class to - // generate iterators that multiply the value returned by dereferencing - // the iterator. In this case we are multiplying by 2. - // Would be cooler to use lambda library in this example. - - int x[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; - - typedef std::binder1st< std::multiplies > Function; - typedef boost::transform_iterator - >::type doubling_iterator; - - doubling_iterator i(x, std::bind1st(std::multiplies(), 2)), - i_end(x + sizeof(x)/sizeof(int), std::bind1st(std::multiplies(), 2)); - - std::cout << "multiplying the array by 2:" << std::endl; - while (i != i_end) - std::cout << *i++ << " "; - std::cout << std::endl; - - // Here is an example of counting from 0 to 5 using the integer_range class. - - boost::integer_range r(0,5); - - std::cout << "counting to from 0 to 4:" << std::endl; - std::copy(r.begin(), r.end(), std::ostream_iterator(std::cout, " ")); - std::cout << std::endl; - - return 0; -} - - diff --git a/iterator_adaptors.htm b/iterator_adaptors.htm deleted file mode 100644 index 7cfb439..0000000 --- a/iterator_adaptors.htm +++ /dev/null @@ -1,784 +0,0 @@ - - - - - - - - - - Boost Iterator Adaptor Library - - - - - c++boost.gif (8819 bytes) - -

Boost Iterator Adaptor Library

- -

Introduction

- -

The Iterator Adaptor library allows you transform an arbitrary ``base'' - type into a standard-conforming iterator with the behaviors you choose. - Doing so is especially easy if the ``base'' type is itself an iterator. The - library also supplies several example adaptors which apply - specific useful behaviors to arbitrary base iterators. - -

Table of Contents

- - - -

Dave - Abrahams started the library, applying policy class technique and - handling const/non-const iterator interactions. He also contributed the - indirect_ and reverse_ iterator generators, and expanded - counting_iterator_generator to - cover all incrementable types. He edited most of the documentation, - sometimes heavily.
- Jeremy - Siek contributed the transform - iterator adaptor, the integer-only version of counting_iterator_generator, and most of - the documentation.
- John - Potter contributed the projection_ and filter_ iterator generators and made some - simplifications to the main iterator_adaptor template.
- - -

Class template - iterator_adaptor

- Implementing standard conforming iterators is a non-trivial task. There are - some fine points such as the interactions between an iterator and its - corresponding const_iterator, and there are myriad operators that should be - implemented but are easily forgotten or mishandled, such as - operator->(). Using iterator_adaptor, you can easily - implement an iterator class, and even more easily extend and adapt existing iterator - types. Moreover, it is easy to make a pair of interoperable const - and non-const iterators. - -

iterator_adaptor is declared like this: -

-template <class Base, class Policies, 
-    class Value = typename std::iterator_traits<Base>::value_type,
-    class Reference = ...(see below),
-    class Pointer = ...(see below),
-    class Category = typename std::iterator_traits<Base>::iterator_category,
-    class Distance = typename std::iterator_traits<Base>::difference_type>
-struct iterator_adaptor;
-
- -

Template Parameters

- -

Although iterator_adaptor takes seven template parameters, - defaults have been carefully chosen to minimize the number of parameters - you must supply in most cases, especially if BaseType is an - iterator. - - - - - - - - - - -
Parameter - - Description - -
BaseType - - The type being wrapped. - -
Policies - - A policy - class that supplies core functionality to the resulting iterator. A - detailed description can be found below. - -
Value - - The value_type of the resulting iterator, unless const. If - Value is const X the - value_type will be (non-const) X[1].
- Default: - std::iterator_traits<BaseType>::value_type [2] - -
Reference - - The reference type of the resulting iterator, and in - particular, the result type of operator*().
- Default: If Value is supplied, Value& is - used. Otherwise - std::iterator_traits<BaseType>::reference is used. - -
Pointer - - The pointer type of the resulting iterator, and in - particular, the result type of operator->().
- Default: If Value was supplied, then Value*, - otherwise std::iterator_traits<BaseType>::pointer. - -
Category - - The iterator_category type for the resulting iterator.
- Default: - std::iterator_traits<BaseType>::iterator_category - -
Distance - - The difference_type for the resulting iterator.
- Default: - std::iterator_traits<BaseType>::difference_type -
- -

The Policies Class

- -

The main task in using iterator_adaptor is creating an - appropriate Policies class. The Policies class will - become the functional heart of the iterator adaptor, supplying the core - iterator operations that will determine how your new adaptor class will - behave. The iterator_adaptor template defines all of the operators - required of a Random Access - Iterator. Your Policies class must implement three, four, or - seven of the core iterator operations below depending on the iterator - categories you want it to support.
-
- - - - - - - - - - - - - -
- Core Iterator Operations
- T: iterator type; p: object of type T; n: T::size_type; x: T::difference_type; p1, p2: iterators -
Operation - - Effects - - Implements Operations - - Required for Iterator Categories - -
dereference - - returns an element of the iterator's reference type - - *p, p[n] - - Input/ Output/ Forward/ Bidirectional/ - Random - Access - -
equal - - tests the iterator for equality - - p1 == p2, p1 != p2 - -
increment - - increments the iterator - - ++p, p++ - -
decrement - - decrements the iterator - - --p, p-- - - Bidirectional/ - Random - Access - -
less - - imposes a Strict Weak - Ordering relation on iterators - - - p1 < p2, - p1 <= p2, - p1 > p2, - p1 >= p2 - - Random - Access - -
distance - - measures the distance between iterators - - p1 - p2 - -
advance - - adds an integer offset to iterators - - -p + x, -x + p, -p += x, -p - x, -p -= x - -
- -

The library also supplies a "trivial" policy class, - default_iterator_policies, which implements all seven of the core - operations in the usual way. If you wish to create an iterator adaptor that - only changes a few of the base type's behaviors, then you can derive your - new policy class from default_iterator_policies to avoid retyping - the usual behaviors. You should also look at - default_iterator_policies as the ``boilerplate'' for your own - policy classes, defining functions with the same interface. This is the - definition of default_iterator_policies:
-
- -

-
-struct default_iterator_policies
-{
-  template <class Reference, class BaseType>
-  Reference dereference(type<Reference>, const BaseType& x) const
-    { return *x; }
-
-  template <class BaseType>
-  static void increment(BaseType& x)
-    { ++x; }
-
-  template <class BaseType1, class BaseType2>
-  bool equal(BaseType1& x, BaseType2& y) const
-    { return x == y; }
-
-  template <class BaseType>
-  static void decrement(BaseType& x)
-    { --x; }
-
-  template <class BaseType, class DifferenceType>
-  static void advance(BaseType& x, DifferenceType n)
-    { x += n; }
-
-  template <class Difference, class BaseType1, class BaseType2>
-  Difference distance(type<Difference>, BaseType1& x, BaseType2& y) const
-    { return y - x; }
-
-  template <class BaseType1, class BaseType2>
-  bool less(BaseType1& x, BaseType2& y) const
-    { return x < y; }
-};
-
-
- -

Template member functions are used throughout - default_iterator_policies so that it can be employed with a wide - range of iterators. If we had used concrete types above, we'd have tied the - usefulness of default_iterator_policies to a particular range of - adapted iterators. If you follow the same pattern with your - Policies classes, you may achieve the same sort of reusability. - -

Additional Members

- In addition to all of the member functions required of a Random Access - Iterator, the iterator_adaptor class template defines the - following members.
-
- - - - - - -
explicit iterator_adaptor(const Base&, const Policies& = - Policies()) -

- Construct an adapted iterator from a base object and a policies - object. As this constructor is explicit, it does not - provide for implicit conversions from the Base type to - the iterator adaptor. - -
template <class B, class V, class R, class P>
- iterator_adaptor(const - iterator_adaptor<B,Policies,V,R,P,Category,Distance>&)
-

- This constructor allows for conversion from non-const to - constant adapted iterators. See below for more details.
- Requires: B is convertible to Base. - -
base_type base() const; -

- Return a copy of the base object. -
- -

Example

- -

It is often useful to automatically apply some function to the value - returned by dereferencing an iterator. The transform iterator makes it easy to create - an iterator adaptor which does just that. Here we will show how easy it is - to implement the transform iterator using the iterator_adaptor - template. - -

We want to be able to adapt a range of iterators and functions, so the - policies class will have a template parameter for the function type and it - will have a data member of that type. We know that the function takes one - argument and that we'll need to be able to deduce the result_type - of the function so we can use it for the adapted iterator's - value_type. AdaptableUnaryFunction - is the Concept - that fulfills those requirements. - -

To implement a transform iterator we will only change one of the base - iterator's behaviors, so the transform_iterator_policies class can - inherit the rest from default_iterator_policies. We will define - the dereference() member function, which is used to implement - operator*() of the adapted iterator. The implementation will - dereference the base iterator and apply the function object. The - type<Reference> parameter is used to convey the appropriate - return type. The complete code for transform_iterator_policies - is:
-
- - -

-
-  template <class AdaptableUnaryFunction>
-  struct transform_iterator_policies : public default_iterator_policies
-  {
-    transform_iterator_policies() { }
-
-    transform_iterator_policies(const AdaptableUnaryFunction& f)
-      : m_f(f) { }
-
-    template <class Reference, class BaseIterator>
-    Reference dereference(type<Reference>, const BaseIterator& i) const
-      { return m_f(*i); }
-
-    AdaptableUnaryFunction m_f;
-  };
-
-
- -

The next step is to use the iterator_adaptor template to - construct the transform iterator type. The nicest way to package the - construction of the transform iterator is to create a type generator. - The first template parameter to the generator will be the type of the - function object and the second will be the base iterator type. We use - iterator_adaptor to define the transform iterator type as a nested - typedef inside the transform_iterator_generator class. - Because the function may return by-value, we must limit the - iterator_category to Input Iterator, and - the iterator's reference type cannot be a true reference (the - standard allows this for input iterators), so in this case we can use few - of iterator_adaptor's default template arguments.
-
- - -

-
-template <class AdaptableUnaryFunction, class Iterator>
-struct transform_iterator_generator
-{
-    typedef typename AdaptableUnaryFunction::result_type value_type;
-public:
-    typedef iterator_adaptor<Iterator, 
-        transform_iterator_policies<AdaptableUnaryFunction>,
-        value_type, value_type, value_type*, std::input_iterator_tag>
-      type;
-};
-
-
- -

As a finishing touch, we will create an object generator - for the transform iterator. This is a function that makes it more - convenient to create a transform iterator.
-
- - -

-
-template <class AdaptableUnaryFunction, class Iterator>
-typename transform_iterator_generator<AdaptableUnaryFunction,Iterator>::type
-make_transform_iterator(Iterator base,
-                        const AdaptableUnaryFunction& f = AdaptableUnaryFunction())
-{
-    typedef typename transform_iterator_generator<AdaptableUnaryFunction,
-      Iterator>::type result_t;
-    return result_t(base, f);
-}
-
-
- -

Here is an example that shows how to use a transform iterator to iterate - through a range of numbers, multiplying each of them by 2 and printing the - result to standard output.
-
- - -

-
-#include <functional>
-#include <algorithm>
-#include <iostream>
-#include <boost/iterator_adaptors.hpp>
-
-int main(int, char*[])
-{
-  int x[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
-  const int N = sizeof(x)/sizeof(int);
-  std::cout << "multiplying the array by 2:" << std::endl;
-  std::copy(boost::make_transform_iterator(x, std::bind1st(std::multiplies<int>(), 2)),
-      boost::make_transform_iterator(x + N, std::bind1st(std::multiplies<int>(), 2)),
-      std::ostream_iterator<int>(std::cout, " "));
-  std::cout << std::endl;
-  return 0;
-}
-
- This output is: -
-2 4 6 8 10 12 14 16
-
-
- -

Iterator Interactions

- -

C++ allows const and non-const pointers to interact in - the following intuitive ways: - -

    -
  • a non-const pointer to T can be implicitly - converted to a const pointer to T. - -
  • const and non-const pointers to T can be - freely mixed in comparison expressions. - -
  • const and non-const pointers to T can be - freely subtracted, in any order. -
- - Getting user-defined iterators to work together that way is nontrivial (see - here for an example of where - the C++ standard got it wrong), but iterator_adaptor can make it - easy. The rules are as follows: - -
    -
  • Adapted iterators that share the same Policies, - Category, and Distance parameters are called - interoperable. - -
  • An adapted iterator can be implicitly converted to any other adapted - iterator with which it is interoperable, so long as the Base - type of the source iterator can be converted to the Base type of - the target iterator. - -
  • Interoperable iterators can be freely mixed in comparison expressions - so long as the Policies class has equal (and, for - random access iterators, less) members that can accept both - Base types in either order. - -
  • Interoperable iterators can be freely mixed in subtraction - expressions so long as the Policies class has a - distance member that can accept both Base types in - either order. -
- -

Example

- -

The Projection Iterator adaptor is similar to the transform iterator adaptor in that -its operator*() applies some function to the result of -dereferencing the base iterator and then returns the result. The -difference is that the function must return a reference to some -existing object (for example, a data member within the -value_type of the base iterator). - -

-The projection_iterator_pair_generator template - is a special two-type generator for mutable and constant versions of a - projection iterator. It is defined as follows: -

-
-template <class AdaptableUnaryFunction, class Iterator, class ConstIterator>
-struct projection_iterator_pair_generator {
-    typedef typename AdaptableUnaryFunction::result_type value_type;
-    typedef projection_iterator_policies<AdaptableUnaryFunction> policies;
-public:
-    typedef iterator_adaptor<Iterator,policies,value_type> iterator;
-    typedef iterator_adaptor<ConstIterator,policies,value_type,
-        const value_type&,const value_type*> const_iterator;
-};
-
-
- -

It is assumed that the Iterator and ConstIterator arguments are corresponding mutable -and constant iterators.

    -
  • -Clearly, then, the -projection_iterator_pair_generator's iterator and -const_iterator are interoperable, since -they share the same Policies and since Category and -Distance as supplied by std::iterator_traits through the -default template parameters to -iterator_adaptor should be the same. - -
  • Since Iterator can presumably be converted to -ConstIterator, the projection iterator will be convertible to -the projection const_iterator. - -
  • Since projection_iterator_policies implements only the -dereference operation, and inherits all other behaviors from default_iterator_policies, which has -fully-templatized equal, less, and distance -operations, the iterator and const_iterator can be freely -mixed in comparison and subtraction expressions. - -
- -

Challenge

- -

There is an unlimited number of ways the iterator_adaptors - class can be used to create iterators. One interesting exercise would be to - re-implement the iterators of std::list and std::slist - using iterator_adaptors, where the adapted Iterator types - would be node pointers. - -

Concept Model

- Depending on the Base and Policies template parameters, - an iterator_adaptor can be a Input Iterator, Forward - Iterator, Bidirectional - Iterator, or Random Access - Iterator. - -

Declaration Synopsis

-
-template <class Base, class Policies, 
-    class Value = typename std::iterator_traits<Base>::value_type,
-    class Reference = ...(see below),
-    class Pointer = ...(see below),
-    class Category = typename std::iterator_traits<Base>::iterator_category,
-    class Distance = typename std::iterator_traits<Base>::difference_type
-         >
-struct iterator_adaptor
-{
-    typedef Distance difference_type;
-    typedef typename boost::remove_const<Value>::type value_type;
-    typedef Pointer pointer;
-    typedef Reference reference;
-    typedef Category iterator_category;
-    typedef Base base_type;
-    typedef Policies policies_type;
-
-    iterator_adaptor();
-    explicit iterator_adaptor(const Base&, const Policies& = Policies());
-
-    base_type base() const;
-
-    template <class B, class V, class R, class P>
-    iterator_adaptor(
-        const iterator_adaptor<B,Policies,V,R,P,Category,Distance>&);
-
-    reference operator*() const;
-    operator_arrow_result_type operator->() const; [3]
-    value_type operator[](difference_type n) const; [4]
-
-    iterator_adaptor& operator++();
-    iterator_adaptor& operator++(int);
-    iterator_adaptor& operator--();
-    iterator_adaptor& operator--(int);
-
-    iterator_adaptor& operator+=(difference_type n);
-    iterator_adaptor& operator-=(difference_type n);
-
-    iterator_adaptor& operator-(Distance x) const;
-};
-
-template <class B, class P, class V, class R, class Ptr, 
-    class C, class D1, class D2>
-iterator_adaptor<B,P,V,R,Ptr,C,D1>
-operator+(iterator_adaptor<B,P,V,R,Ptr,C,D1>, D2);
-
-template <class B, class P, class V, class R, class Ptr,
-    class C, class D1, class D2>
-iterator_adaptor<B,P,V,R,P,C,D1>
-operator+(D2, iterator_adaptor<B,P,V,R,Ptr,C,D1> p);
-
-template <class B1, class B2, class P, class V1, class V2,
-    class R1, class R2, class P1, class P2, class C, class D>
-Distance operator-(const iterator_adaptor<B1,P,V1,R1,P1,C,D>&, 
-                   const iterator_adaptor<B2,P,V2,R2,P2,C,D>&);
-
-template <class B1, class B2, class P, class V1, class V2,
-    class R1, class R2, class P1, class P2, class C, class D>
-bool operator==(const iterator_adaptor<B1,P,V1,R1,P1,C,D>&, 
-                const iterator_adaptor<B2,P,V2,R2,P2,C,D>&);
-
-// and similarly for operators !=, <, <=, >=, >
-
- -

Notes

- -

[1] The standard specifies that the value_type - of const iterators to T (e.g. const T*) is - non-const T, while the pointer and - reference types for all Forward Iterators are - const T* and const T&, respectively. Stripping the - const-ness of Value allows you to easily - make a const iterator adaptor by supplying a const type - for Value, and allowing the defaults for the Pointer and - Reference parameters to take effect. Although compilers that don't - support partial specialization won't strip const for you, having a - const value_type is often harmless in practice. - -

[2] If your compiler does not support partial - specialization and the base iterator is a builtin pointer type, you - will not be able to use the default for Value and will have to - specify this type explicitly. - -

[3] The result type for the operator->() - depends on the category and value type of the iterator and is somewhat - complicated to describe. But be assured, it works in a stardard conforming - fashion, providing access to members of the objects pointed to by the - iterator. - -

[4] The result type of operator[]() is - value_type instead of reference as might be expected. - There are two reasons for this choice. First, the C++ standard only - requires that the return type of an arbitrary Random Access - Iterator's operator[]be ``convertible to T'' (Table 76), so - when adapting an arbitrary base iterator we may not have a reference to - return. Second, and more importantly, for certain kinds of iterators, - returning a reference could cause serious memory problems due to the - reference being bound to a temporary object whose lifetime ends inside of - the operator[]. -


- -

Revised - 15 - Feb 2001 - - -

© Copyright Dave Abrahams and Jeremy Siek 2001. 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" - without express or implied warranty, and with no claim as to its - suitability for any purpose. - - - - - - - - - - - - - - - diff --git a/iterator_traits_test.cpp b/iterator_traits_test.cpp deleted file mode 100644 index a568903..0000000 --- a/iterator_traits_test.cpp +++ /dev/null @@ -1,209 +0,0 @@ -// (C) Copyright David Abrahams 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 -// 19 Feb 2001 Take advantage of improved iterator_traits to do more tests -// on MSVC. Reordered some #ifdefs for coherency. -// (David Abrahams) -// 13 Feb 2001 Test new VC6 workarounds (David Abrahams) -// 11 Feb 2001 Final fixes for Borland (David Abrahams) -// 11 Feb 2001 Some fixes for Borland get it closer on that compiler -// (David Abrahams) -// 07 Feb 2001 More comprehensive testing; factored out static tests for -// better reuse (David Abrahams) -// 21 Jan 2001 Quick fix to my_iterator, which wasn't returning a -// reference type from operator* (David Abrahams) -// 19 Jan 2001 Initial version with iterator operators (David Abrahams) - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// An iterator for which we can get traits. -struct my_iterator1 - : boost::forward_iterator_helper -{ - my_iterator1(const char* p) : m_p(p) {} - - bool operator==(const my_iterator1& rhs) const - { return this->m_p == rhs.m_p; } - - my_iterator1& operator++() { ++this->m_p; return *this; } - const char& operator*() { return *m_p; } - private: - const char* m_p; -}; - -// Used to prove that we don't require std::iterator<> in the hierarchy under -// MSVC6, and that we can compute all the traits for a standard-conforming UDT -// iterator. -struct my_iterator2 - : boost::equality_comparable > > -{ - typedef char value_type; - typedef long difference_type; - typedef const char* pointer; - typedef const char& reference; - typedef std::forward_iterator_tag iterator_category; - - my_iterator2(const char* p) : m_p(p) {} - - bool operator==(const my_iterator2& rhs) const - { return this->m_p == rhs.m_p; } - - my_iterator2& operator++() { ++this->m_p; return *this; } - const char& operator*() { return *m_p; } - private: - const char* m_p; -}; - -// Used to prove that we're not overly confused by the existence of -// std::iterator<> in the hierarchy under MSVC6 - we should find that -// boost::detail::iterator_traits::difference_type is int. -struct my_iterator3 : my_iterator1 -{ - typedef int difference_type; - my_iterator3(const char* p) : my_iterator1(p) {} -}; - -template -struct non_portable_tests -{ - // Unfortunately, the VC6 standard library doesn't supply these :( - BOOST_STATIC_ASSERT(( - boost::is_same< - typename boost::detail::iterator_traits::pointer, - pointer - >::value)); - - BOOST_STATIC_ASSERT(( - boost::is_same< - typename boost::detail::iterator_traits::reference, - reference - >::value)); -}; - -template -struct portable_tests -{ - BOOST_STATIC_ASSERT(( - boost::is_same< - typename boost::detail::iterator_traits::difference_type, - difference_type - >::value)); - - BOOST_STATIC_ASSERT(( - boost::is_same< - typename boost::detail::iterator_traits::iterator_category, - category - >::value)); -}; - -// Test iterator_traits -template -struct input_iterator_test - : portable_tests -{ - BOOST_STATIC_ASSERT(( - boost::is_same< - typename boost::detail::iterator_traits::value_type, - value_type - >::value)); -}; - -template -struct non_pointer_test - : input_iterator_test - , non_portable_tests -{ -}; - -template -struct maybe_pointer_test - : portable_tests -#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION - , non_portable_tests -#endif -{ -}; - -input_iterator_test, int, std::ptrdiff_t, int*, int&, std::input_iterator_tag> - istream_iterator_test; - -// -#if defined(__BORLANDC__) && !defined(__SGI_STL_PORT) -typedef ::std::char_traits::off_type distance; -non_pointer_test,int, - distance,int*,int&,std::output_iterator_tag> ostream_iterator_test; -#elif defined(BOOST_MSVC) && !defined(__SGI_STL_PORT) -non_pointer_test, - int, void, void, void, std::output_iterator_tag> - ostream_iterator_test; -#else -non_pointer_test, - void, void, void, void, std::output_iterator_tag> - ostream_iterator_test; -#endif - - -#ifdef __KCC - typedef long std_list_diff_type; -#else - typedef std::ptrdiff_t std_list_diff_type; -#endif -non_pointer_test::iterator, int, std_list_diff_type, int*, int&, std::bidirectional_iterator_tag> - list_iterator_test; - -maybe_pointer_test::iterator, int, std::ptrdiff_t, int*, int&, std::random_access_iterator_tag> - vector_iterator_test; - -maybe_pointer_test - int_pointer_test; - -non_pointer_test - my_iterator1_test; - -non_pointer_test - my_iterator2_test; - -non_pointer_test - my_iterator3_test; - -int main() -{ - char chars[100]; - int ints[100]; - - for (std::ptrdiff_t length = 3; length < 100; length += length / 3) - { - std::list l(length); - assert(boost::detail::distance(l.begin(), l.end()) == length); - - std::vector v(length); - assert(boost::detail::distance(v.begin(), v.end()) == length); - - assert(boost::detail::distance(&ints[0], ints + length) == length); - assert(boost::detail::distance(my_iterator1(chars), my_iterator1(chars + length)) == length); - assert(boost::detail::distance(my_iterator2(chars), my_iterator2(chars + length)) == length); - assert(boost::detail::distance(my_iterator3(chars), my_iterator3(chars + length)) == length); - } - return 0; -} diff --git a/iterators_test.cpp b/iterators_test.cpp deleted file mode 100644 index e264aff..0000000 --- a/iterators_test.cpp +++ /dev/null @@ -1,169 +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 -// 12 Dec 99 Initial version with iterator operators (Jeremy Siek) - -#include -#include -using namespace std; - -#include -using namespace boost; - - -template -struct test_iter - : public boost::random_access_iterator_helper< - test_iter, T, std::ptrdiff_t, P, R> -{ - typedef test_iter self; - typedef R Reference; - typedef std::ptrdiff_t Distance; - -public: - test_iter(T* i) : _i(i) { } - test_iter(const self& x) : _i(x._i) { } - self& operator=(const self& x) { _i = x._i; return *this; } - Reference operator*() const { return *_i; } - self& operator++() { ++_i; return *this; } - self& operator--() { --_i; return *this; } - self& operator+=(Distance n) { _i += n; return *this; } - self& operator-=(Distance n) { _i -= n; return *this; } - bool operator==(const self& x) const { return _i == x._i; } - bool operator<(const self& x) const { return _i < x._i; } - friend Distance operator-(const self& x, const self& y) { - return x._i - y._i; - } -protected: - T* _i; -}; - - -int -main() -{ - string array[] = { "apple", "orange", "pear", "peach", "grape", "plum" }; - { - test_iter i = array, - ie = array + sizeof(array)/sizeof(string); - - // Tests for all of the operators added by random_access_iterator_helper - - // test i++ - while (i != ie) - cout << *i++ << " "; - cout << endl; - i = array; - - // test i-- - while (ie != i) { - ie--; - cout << *ie << " "; - } - cout << endl; - ie = array + sizeof(array)/sizeof(string); - - // test i->m - while (i != ie) { - cout << i->size() << " "; - ++i; - } - cout << endl; - i = array; - - // test i + n - while (i < ie) { - cout << *i << " "; - i = i + 2; - } - cout << endl; - i = array; - - // test n + i - while (i < ie) { - cout << *i << " "; - i = ptrdiff_t(2) + i; - } - cout << endl; - i = array; - - // test i - n - while (ie > i) { - ie = ie - 2; - cout << *ie << " "; - } - cout << endl; - ie = array + sizeof(array)/sizeof(string); - - // test i[n] - for (std::size_t j = 0; j < sizeof(array)/sizeof(string); ++j) - cout << i[j] << " "; - cout << endl; - } - { - test_iter i = array, - ie = array + sizeof(array)/sizeof(string); - - // Tests for all of the operators added by random_access_iterator_helper - - // test i++ - while (i != ie) - cout << *i++ << " "; - cout << endl; - i = array; - - // test i-- - while (ie != i) { - ie--; - cout << *ie << " "; - } - cout << endl; - ie = array + sizeof(array)/sizeof(string); - - // test i->m - while (i != ie) { - cout << i->size() << " "; - ++i; - } - cout << endl; - i = array; - - // test i + n - while (i < ie) { - cout << *i << " "; - i = i + 2; - } - cout << endl; - i = array; - - // test n + i - while (i < ie) { - cout << *i << " "; - i = ptrdiff_t(2) + i; - } - cout << endl; - i = array; - - // test i - n - while (ie > i) { - ie = ie - 2; - cout << *ie << " "; - } - cout << endl; - ie = array + sizeof(array)/sizeof(string); - - // test i[n] - for (std::size_t j = 0; j < sizeof(array)/sizeof(string); ++j) - cout << i[j] << " "; - cout << endl; - } - return 0; -} diff --git a/noncopyable_test.cpp b/noncopyable_test.cpp deleted file mode 100644 index e5103fb..0000000 --- a/noncopyable_test.cpp +++ /dev/null @@ -1,38 +0,0 @@ -// boost class noncopyable test program ------------------------------------// - -// (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. - -// Revision History -// 9 Jun 99 Add unnamed namespace -// 2 Jun 99 Initial Version - -#include -#include - -// This program demonstrates compiler errors resulting from trying to copy -// construct or copy assign a class object derived from class noncopyable. - -namespace -{ - class DontTreadOnMe : boost::noncopyable - { - public: - DontTreadOnMe() { std::cout << "defanged!" << std::endl; } - }; // DontTreadOnMe - -} // unnamed namespace - -int main() -{ - DontTreadOnMe object1; - DontTreadOnMe object2(object1); - object1 = object2; - return 0; -} // main - \ No newline at end of file diff --git a/numeric_traits_test.cpp b/numeric_traits_test.cpp deleted file mode 100644 index 3b169bf..0000000 --- a/numeric_traits_test.cpp +++ /dev/null @@ -1,393 +0,0 @@ -// (C) Copyright David Abrahams 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 -// 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 -// warnings with fancy compilers. Added commentary and -// additional dumping of traits data for tested types (David -// Abrahams). -// 21 Jan 2001 Initial version (David Abrahams) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifndef BOOST_NO_LIMITS -# include -#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 -- -// -// statically computes the max and min for 1s and 2s-complement binary -// numbers. This helps on platforms without support. It also shows -// an example of a recursive template that works with MSVC! -// - -template struct complement; // forward - -// The template complement, below, does all the real work, using "poor man's -// partial specialization". We need complement_traits_aux<> so that MSVC doesn't -// complain about undefined min/max as we're trying to recursively define them. -template -struct complement_traits_aux -{ - DECLARE_CLASS_CONST(Number, max = complement::template traits::max); - DECLARE_CLASS_CONST(Number, min = complement::template traits::min); -}; - -template -struct complement -{ - template - struct traits - { - private: - // indirection through complement_traits_aux neccessary to keep MSVC happy - typedef complement_traits_aux prev; - public: - DECLARE_CLASS_CONST(Number, max = - Number(Number(prev::max) << CHAR_BIT) - + Number(UCHAR_MAX)); - - DECLARE_CLASS_CONST(Number, min = Number(Number(prev::min) << CHAR_BIT)); - }; -}; - -// Template class complement_base<> -- defines values for min and max for -// complement<1>, at the deepest level of recursion. Uses "poor man's partial -// specialization" again. -template struct complement_base; - -template <> struct complement_base -{ - template - struct values - { - DECLARE_CLASS_CONST(Number, min = 0); - DECLARE_CLASS_CONST(Number, max = UCHAR_MAX); - }; -}; - -template <> struct complement_base -{ - template - struct values - { - DECLARE_CLASS_CONST(Number, min = SCHAR_MIN); - DECLARE_CLASS_CONST(Number, max = SCHAR_MAX); - }; -}; - -// Base specialization of complement, puts an end to the recursion. -template <> -struct complement<1> -{ - template - struct traits - { - DECLARE_CLASS_CONST(bool, is_signed = boost::detail::is_signed::value); - DECLARE_CLASS_CONST(Number, min = - complement_base::template values::min); - DECLARE_CLASS_CONST(Number, max = - complement_base::template values::max); - }; -}; - -// Now here's the "pretty" template you're intended to actually use. -// complement_traits::min, complement_traits::max are the -// minimum and maximum values of Number if Number is a built-in integer type. -template -struct complement_traits -{ - DECLARE_CLASS_CONST(Number, max = (complement_traits_aux::max)); - DECLARE_CLASS_CONST(Number, min = (complement_traits_aux::min)); -}; - -// ================================================================================= - -// Support for streaming various numeric types in exactly the format I want. I -// needed this in addition to all the assertions so that I could see exactly -// what was going on. -// -// Numbers go through a 2-stage conversion process (by default, though, no real -// conversion). -// -template struct stream_as { - typedef T t1; - typedef T t2; -}; - -// char types first get converted to unsigned char, then to unsigned. -template <> struct stream_as { - typedef unsigned char t1; - typedef unsigned t2; -}; -template <> struct stream_as { - typedef unsigned char t1; typedef unsigned t2; -}; -template <> struct stream_as { - typedef unsigned char t1; typedef unsigned t2; -}; - -#if defined(BOOST_MSVC) // No intmax streaming built-in - -// On this platform, __int64 and __uint64 get streamed as strings -template <> struct stream_as { - typedef std::string t1; - typedef std::string t2; -}; - -template <> struct stream_as { - typedef std::string t1; - typedef std::string t2; -}; -#endif - -// Standard promotion process for streaming -template struct promote -{ - static typename stream_as::t1 from(T x) { - typedef typename stream_as::t1 t1; - return t1(x); - } -}; - -#if defined(BOOST_MSVC) // No intmax streaming built-in - -// On this platform, stream them as long/unsigned long if they fit. -// Otherwise, write a string. -template <> struct promote { - std::string static from(const boost::uintmax_t x) { - if (x > ULONG_MAX) - return std::string("large unsigned value"); - else - return boost::lexical_cast((unsigned long)x); - } -}; -template <> struct promote { - std::string static from(const boost::intmax_t x) { - if (x > boost::intmax_t(ULONG_MAX)) - return std::string("large positive signed value"); - else if (x >= 0) - return boost::lexical_cast((unsigned long)x); - - if (x < boost::intmax_t(LONG_MIN)) - return std::string("large negative signed value"); - else - return boost::lexical_cast((long)x); - } -}; -#endif - -// This is the function which converts types to the form I want to stream them in. -template -typename stream_as::t2 stream_number(T x) -{ - return promote::from(x); -} -// ================================================================================= - -// -// Tests for built-in signed and unsigned types -// - -// Tag types for selecting tests -struct unsigned_tag {}; -struct signed_tag {}; - -// Tests for unsigned numbers. The extra default Number parameter works around -// an MSVC bug. -template -void test_aux(unsigned_tag, Number* = 0) -{ - typedef typename boost::detail::numeric_traits::difference_type difference_type; - BOOST_STATIC_ASSERT(!boost::detail::is_signed::value); - BOOST_STATIC_ASSERT( - (sizeof(Number) < sizeof(boost::intmax_t)) - | (boost::is_same::value)); - - // Force casting to Number here to work around the fact that it's an enum on MSVC - BOOST_STATIC_ASSERT(Number(complement_traits::max) > Number(0)); - BOOST_STATIC_ASSERT(Number(complement_traits::min) == Number(0)); - - const Number max = complement_traits::max; - const Number min = complement_traits::min; - - const Number test_max = (sizeof(Number) < sizeof(boost::intmax_t)) - ? max - : max / 2 - 1; - - std::cout << std::hex << "(unsigned) min = " << stream_number(min) << ", max = " - << stream_number(max) << "..." << std::flush; - std::cout << "difference_type = " << typeid(difference_type).name() << "..." - << std::flush; - - difference_type d1 = boost::detail::numeric_distance(Number(0), test_max); - difference_type d2 = boost::detail::numeric_distance(test_max, Number(0)); - - std::cout << "0->" << stream_number(test_max) << "==" << std::dec << stream_number(d1) << "; " - << std::hex << stream_number(test_max) << "->0==" << std::dec << stream_number(d2) << "..." << std::flush; - - assert(d1 == difference_type(test_max)); - assert(d2 == -difference_type(test_max)); -} - -// Tests for signed numbers. The extra default Number parameter works around an -// MSVC bug. -struct out_of_range_tag {}; -struct in_range_tag {}; - -// This test morsel gets executed for numbers whose difference will always be -// representable in intmax_t -template -void signed_test(in_range_tag, Number* = 0) -{ - BOOST_STATIC_ASSERT(boost::detail::is_signed::value); - typedef typename boost::detail::numeric_traits::difference_type difference_type; - const Number max = complement_traits::max; - const Number min = complement_traits::min; - - difference_type d1 = boost::detail::numeric_distance(min, max); - difference_type d2 = boost::detail::numeric_distance(max, min); - - std::cout << stream_number(min) << "->" << stream_number(max) << "=="; - std::cout << std::dec << stream_number(d1) << "; "; - std::cout << std::hex << stream_number(max) << "->" << stream_number(min) - << "==" << std::dec << stream_number(d2) << "..." << std::flush; - assert(d1 == difference_type(max) - difference_type(min)); - assert(d2 == difference_type(min) - difference_type(max)); -} - -// This test morsel gets executed for numbers whose difference may exceed the -// capacity of intmax_t. -template -void signed_test(out_of_range_tag, Number* = 0) -{ - BOOST_STATIC_ASSERT(boost::detail::is_signed::value); - typedef typename boost::detail::numeric_traits::difference_type difference_type; - const Number max = complement_traits::max; - const Number min = complement_traits::min; - - difference_type min_distance = complement_traits::min; - difference_type max_distance = complement_traits::max; - - const Number n1 = Number(min + max_distance); - const Number n2 = Number(max + min_distance); - difference_type d1 = boost::detail::numeric_distance(min, n1); - difference_type d2 = boost::detail::numeric_distance(max, n2); - - std::cout << stream_number(min) << "->" << stream_number(n1) << "=="; - std::cout << std::dec << stream_number(d1) << "; "; - std::cout << std::hex << stream_number(max) << "->" << stream_number(n2) - << "==" << std::dec << stream_number(d2) << "..." << std::flush; - assert(d1 == max_distance); - assert(d2 == min_distance); -} - -template -void test_aux(signed_tag, Number* = 0) -{ - typedef typename boost::detail::numeric_traits::difference_type difference_type; - BOOST_STATIC_ASSERT(boost::detail::is_signed::value); - BOOST_STATIC_ASSERT( - (sizeof(Number) < sizeof(boost::intmax_t)) - | (boost::is_same::value)); - - // Force casting to Number here to work around the fact that it's an enum on MSVC - BOOST_STATIC_ASSERT(Number(complement_traits::max) > Number(0)); - BOOST_STATIC_ASSERT(Number(complement_traits::min) < Number(0)); - - const Number max = complement_traits::max; - const Number min = complement_traits::min; - - std::cout << std::hex << "min = " << stream_number(min) << ", max = " - << stream_number(max) << "..." << std::flush; - std::cout << "difference_type = " << typeid(difference_type).name() << "..." - << std::flush; - - typedef typename boost::detail::if_true< - (sizeof(Number) < sizeof(boost::intmax_t))> - ::template then< - in_range_tag, - out_of_range_tag - >::type - range_tag; - signed_test(range_tag()); -} - - -// Test for all numbers. The extra default Number parameter works around an MSVC -// bug. -template -void test(Number* = 0) -{ - std::cout << "testing " << typeid(Number).name() << ":\n" -#ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS - << "is_signed: " << (std::numeric_limits::is_signed ? "true\n" : "false\n") - << "is_bounded: " << (std::numeric_limits::is_bounded ? "true\n" : "false\n") - << "digits: " << std::numeric_limits::digits << "\n" -#endif - << "..." << std::flush; - - // factoring out difference_type for the assert below confused Borland :( - typedef boost::detail::is_signed< -#ifndef BOOST_MSVC - typename -#endif - boost::detail::numeric_traits::difference_type - > is_signed; - BOOST_STATIC_ASSERT(is_signed::value); - - typedef typename boost::detail::if_true< - boost::detail::is_signed::value - >::template then::type signedness; - - test_aux(signedness()); - std::cout << "passed" << std::endl; -} - -int main() -{ - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); - test(); -#if defined(ULLONG_MAX) || defined(ULONG_LONG_MAX) - test(); - test(); -#elif defined(BOOST_MSVC) - // The problem of not having compile-time static class constants other than - // enums prevents this from working, since values get truncated. - // test(); - // test(); -#endif - return 0; -} diff --git a/operators.htm b/operators.htm deleted file mode 100644 index 9812692..0000000 --- a/operators.htm +++ /dev/null @@ -1,597 +0,0 @@ - - - - - - -Header boost/operators.hpp Documentation - - - - -

c++boost.gif (8819 bytes)Header -boost/operators.hpp

-

Header boost/operators.hpp supplies -(in namespace boost) several sets of templates:

- -

These templates define many global operators in terms of a minimal number of -fundamental operators.

-

Arithmetic Operators

-

If, for example, you declare a class like this:

-
-
class MyInt : boost::operators<MyInt>
-{
-    bool operator<(const MyInt& x) const; 
-    bool operator==(const MyInt& x) const;
-    MyInt& operator+=(const MyInt& x);    
-    MyInt& operator-=(const MyInt& x);    
-    MyInt& operator*=(const MyInt& x);    
-    MyInt& operator/=(const MyInt& x);    
-    MyInt& operator%=(const MyInt& x);    
-    MyInt& operator|=(const MyInt& x);    
-    MyInt& operator&=(const MyInt& x);    
-    MyInt& operator^=(const MyInt& x);    
-    MyInt& operator++();    
-    MyInt& operator--();    
-};
-
-

then the operators<> template adds more than a dozen -additional operators, such as operator>, <=, >=, and +.  Two-argument -forms of the templates are also provided to allow interaction with other -types.

-

Dave Abrahams -started the library and contributed the arithmetic operators in boost/operators.hpp.
-Jeremy Siek -contributed the dereference operators and iterator -helpers in boost/operators.hpp.
-Aleksey Gurtovoy -contributed the code to support base class chaining -while remaining backward-compatible with old versions of the library.
-Beman Dawes -contributed test_operators.cpp.

-

Rationale

-

Overloaded operators for class types typically occur in groups. If you can -write x + y, you probably also want to be able to write x += -y. If you can write x < y, you also want x > y, -x >= y, and x <= y. Moreover, unless your class has -really surprising behavior, some of these related operators can be defined in -terms of others (e.g. x >= y <=> !(x < y)). -Replicating this boilerplate for multiple classes is both tedious and -error-prone. The boost/operators.hpp -templates help by generating operators for you at namespace scope based on other -operators you've defined in your class.

- -

Two-Argument Template Forms

-
-

The arguments to a binary operator commonly have identical types, but it is -not unusual to want to define operators which combine different types. For example, -one might want to multiply a mathematical vector by a scalar. The two-argument -template forms of the arithmetic operator templates are supplied for this -purpose. When applying the two-argument form of a template, the desired return -type of the operators typically determines which of the two types in question -should be derived from the operator template. For example, if the result of T + U -is of type T, then T (not U) should be -derived from addable<T,U>. The comparison templates less_than_comparable<> -and equality_comparable<> -are exceptions to this guideline, since the return type of the operators they -define is bool.

-

On compilers which do not support partial specialization, the two-argument -forms must be specified by using the names shown below with the trailing '2'. -The single-argument forms with the trailing '1' are provided for -symmetry and to enable certain applications of the base -class chaining technique.

-

Arithmetic operators table

-

The requirements for the types used to instantiate operator templates are -specified in terms of expressions which must be valid and by the return type of -the expression. In the following table t and t1 are -values of type T, and u is a value of type U. -Every template in the library other than operators<> -and operators2<> has an additional -optional template parameter B which is not shown in the table, but -is explained below

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
templatetemplate will supplyRequirements
operators<T>All the other <T> templates in this table.All the <T> requirements in this table.
operators<T,U>
- operators2<T,U>
All the other <T,U> templates in this table, plus incrementable<T> - and decrementable<T>.All the <T,U> requirements in this table*, - plus incrementable<T> and decrementable<T>.
less_than_comparable<T>
- less_than_comparable1<T>
bool operator>(const T&, const T&) 
- bool operator<=(const T&, const T&)
- bool operator>=(const T&, const T&)
t<t1. Return convertible to bool
less_than_comparable<T,U>
- less_than_comparable2<T,U>
bool operator<=(const T&, const U&)
- bool operator>=(const T&, const U&)
- bool operator>(const U&, const T&) 
- bool operator<(const U&, const T&) 
- bool operator<=(const U&, const T&)
- bool operator>=(const U&, const T&)
t<u. Return convertible to bool
- t>u. Return convertible to bool
equality_comparable<T>
- equality_comparable1<T>
bool operator!=(const T&, const T&)t==t1. Return convertible to bool
equality_comparable<T,U>
- equality_comparable2<T,U>
friend bool operator==(const U&, const T&)
- friend bool operator!=(const U&, const T&)
- friend bool operator!=( const T&, const U&)
t==u. Return convertible to bool
addable<T>
- addable1<T>
T operator+(T, const T&)t+=t1. Return convertible to T
addable<T,U>
- addable2<T,U>
T operator+(T, const U&)
- T operator+(const U&, T )
t+=u. Return convertible to T
subtractable<T>
- subtractable1<T>
T operator-(T, const T&)t-=t1. Return convertible to T
subtractable<T,U>
- subtractable2<T,U>
T operator-(T, const U&)t-=u. Return convertible to T
multipliable<T>
- multipliable1<T>
T operator*(T, const T&)t*=t1. Return convertible to T
multipliable<T,U>
- multipliable2<T,U>
T operator*(T, const U&)
- T operator*(const U&, T )
t*=u. Return convertible to T
dividable<T>
- dividable1<T>
T operator/(T, const T&)t/=t1. Return convertible to T
dividable<T,U>
- dividable2<T,U>
T operator/(T, const U&)t/=u. Return convertible to T
modable<T>
- modable1<T>
T operator%(T, const T&)t%=t1. Return convertible to T
modable<T,U>
- modable2<T,U>
T operator%(T, const U&)t%=u. Return convertible to T
orable<T>
- orable1<T>
T operator|(T, const T&)t|=t1. Return convertible to T
orable<T,U>
- orable2<T,U>
T operator|(T, const U&)
- T operator|(const U&, T )
t|=u. Return convertible to T
andable<T>
- andable1<T>
T operator&(T, const T&)t&=t1. Return convertible to T
andable<T,U>
- andable2<T,U>
T operator&(T, const U&)
- T operator&(const U&, T)
t&=u. Return convertible to T
xorable<T>
- xorable1<T>
T operator^(T, const T&)t^=t1. Return convertible to T
xorable<T,U>
- xorable2<T,U>
T operator^(T, const U&)
- T operator^(const U&, T )
t^=u. Return convertible to T
incrementable<T>
- incrementable1<T>
T operator++(T& x, int)T temp(x); ++x; return temp;
- Return convertible to T
decrementable<T>
- decrementable1<T>
T operator--(T& x, int)T temp(x); --x; return temp;
- Return convertible to T
-
-Portability Note: many compilers (e.g. MSVC6.3, -GCC 2.95.2) will not enforce the requirements in this table unless the -operations which depend on them are actually used. This is not -standard-conforming behavior. If you are trying to write portable code it is -important not to rely on this bug. In particular, it would be convenient to -derive all your classes which need binary operators from the operators<> -and operators2<> templates, -regardless of whether they implement all the requirements in the table. Even if -this works with your compiler today, it may not work tomorrow. -

Base Class Chaining and Object Size

-

Every template listed in the table except operators<> -and operators2<> has an additional -optional template parameter B.  If supplied, B -must be a class type; the resulting class will be publicly derived from B. This -can be used to avoid the object size bloat commonly associated with multiple -empty base classes (see the note for users of older -versions below for more details). To provide support for several groups of -operators, use the additional parameter to chain operator templates into a -single-base class hierarchy, as in the following example.

-

Caveat: to chain to a base class which is not a boost operator -template when using the single-argument form of a -boost operator template, you must specify the operator template with the -trailing '1' in its name. Otherwise the library will assume you -mean to define a binary operation combining the class you intend to use as a -base class and the class you're deriving.

-

Borland users: even single-inheritance seems to cause an increase in -object size in some cases. If you are not defining a template, you may get -better object-size performance by avoiding derivation altogether, and instead -explicitly instantiating the operator template as follows: -

-    class myclass // lose the inheritance...
-    {
-        //...
-    };
-    // explicitly instantiate the operators I need.
-    template class less_than_comparable<myclass>;
-    template class equality_comparable<myclass>;
-    template class incrementable<myclass>;
-    template class decrementable<myclass>;
-    template class addable<myclass,long>;
-    template class subtractable<myclass,long>;
-
-
-

Usage example

-
-
template <class T>
-class point    // note: private inheritance is OK here!
-    : boost::addable< point<T>          // point + point
-    , boost::subtractable< point<T>     // point - point
-    , boost::dividable2< point<T>, T    // point / T
-    , boost::multipliable2< point<T>, T // point * T, T * point
-      > > > >
-{
-public:
-    point(T, T);
-    T x() const;
-    T y() const;
-
-    point operator+=(const point&);
-    // point operator+(point, const point&) automatically
-    // generated by addable.
-
-    point operator-=(const point&);
-    // point operator-(point, const point&) automatically
-    // generated by subtractable.
-
-    point operator*=(T);
-    // point operator*(point, const T&) and
-    // point operator*(const T&, point) auto-generated
-    // by multipliable.
-
-    point operator/=(T);
-    // point operator/(point, const T&) auto-generated
-    // by dividable.
-private:
-    T x_;
-    T y_;
-};
-
-// now use the point<> class:
-
-template <class T>
-T length(const point<T> p)
-{
-    return sqrt(p.x()*p.x() + p.y()*p.y());
-}
-
-const point<float> right(0, 1);
-const point<float> up(1, 0);
-const point<float> pi_over_4 = up + right;
-const point<float> pi_over_4_normalized = pi_over_4 / length(pi_over_4);
-

Arithmetic operators demonstration and test program

-

The operators_test.cpp -program demonstrates the use of the arithmetic operator templates, and can also -be used to verify correct operation.

-

The test program has been compiled and run successfully with: 

-
    -
  • GCC 2.95.2 -
  • GCC 2.95.2 / STLport 4.0b8. -
  • Metrowerks Codewarrior 5.3 -
  • KAI C++ 3.3 -
  • Microsoft Visual C++ 6.0 SP3. -
  • Microsoft Visual C++ 6.0 SP3 / STLport 4.0b8.
  • -
-

Dereference operators and iterator helpers

-

The iterator helper templates ease the task -of creating a custom iterator. Similar to arithmetic types, a complete iterator -has many operators that are "redundant" and can be implemented in -terms of the core set of operators.

-

The dereference operators were motivated by the iterator -helpers, but are often useful in non-iterator contexts as well. Many of the -redundant iterator operators are also arithmetic operators, so the iterator -helper classes borrow many of the operators defined above. In fact, only two new -operators need to be defined! (the pointer-to-member operator-> -and the subscript operator[]). -

Notation

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Tis the user-defined type for which the operations are - being supplied.
Vis the type which the resulting dereferenceable - type "points to", or the value_type of the custom - iterator.
Dis the type used to index the resulting indexable - type or the difference_type of the custom iterator.
Pis a type which can be dereferenced to access V, - or the pointer type of the custom iterator.
Ris the type returned by indexing the indexable - type or the reference type of the custom iterator.
iis short for static_cast<const T&>(*this), - where this is a pointer to the helper class.
- Another words, i should be an object of the custom iterator - type.
x,x1,x2are objects of type T.
nis an object of type D.
-

The requirements for the types used to instantiate the dereference operators -and iterator helpers are specified in terms of expressions which must be valid -and their return type. 

-

Dereference operators

-

The dereference operator templates in this table all accept an optional -template parameter (not shown) to be used for base class -chaining. - - - - - - - - - - - - - - - - - - -
templatetemplate will supplyRequirements
dereferenceable<T,P>P operator->() const(&*i.). Return convertible to P.
indexable<T,D,R>R operator[](D n) const*(i + n). Return of type R.
-

Iterator helpers

-

There are three separate iterator helper classes, each for a different -category of iterator. Here is a summary of the core set of operators that the -custom iterator must define, and the extra operators that are created by the -helper classes. For convenience, the helper classes also fill in all of the -typedef's required of iterators by the C++ standard (iterator_category, -value_type, etc.).

- - - - - - - - - - - - - - - - - - - - - - - -
templatetemplate will supplyRequirements
forward_iterator_helper
- <T,V,D,P,R>
bool operator!=(const T& x1, const T& x2)
- T operator++(T& x, int)
- V* operator->() const
-
x1==x2. Return convertible to bool
- T temp(x); ++x; return temp;
- (&*i.). Return convertible to V*.
bidirectional_iterator_helper
- <T,V,D,P,R>
Same as above, plus
- T operator--(T& x, int)
Same as above, plus
- T temp(x); --x; return temp;
random_access_iterator_helper
- <T,V,D,P,R>
Same as above, plus
- T operator+(T x, const D&)
- T operator+(const D& n, T x)
- T operator-(T x, const D& n)
- R operator[](D n) const
- bool operator>(const T& x1, const T& x2) 
- bool operator<=(const T& x1, const T& x2)
- bool operator>=(const T& x1, const T& x2)
Same as above, plus
- x+=n. Return convertible to T
- x-=n. Return convertible to T
- x1<x2. Return convertible to bool
- And to satisfy RandomAccessIterator:
- x1-x2. Return convertible to D
-

Iterator demonstration and test program

-

The iterators_test.cpp -program demonstrates the use of the iterator templates, and can also be used to -verify correct operation. The following is the custom iterator defined in the -test program. It demonstrates a correct (though trivial) implementation of the -core operations that must be defined in order for the iterator helpers to -"fill in" the rest of the iterator operations.

-
-
template <class T, class R, class P>
-struct test_iter
-  : public boost::random_access_iterator_helper<
-     test_iter<T,R,P>, T, std::ptrdiff_t, P, R>
-{
-  typedef test_iter self;
-  typedef R Reference;
-  typedef std::ptrdiff_t Distance;
-
-public:
-  test_iter(T* i) : _i(i) { }
-  test_iter(const self& x) : _i(x._i) { }
-  self& operator=(const self& x) { _i = x._i; return *this; }
-  Reference operator*() const { return *_i; }
-  self& operator++() { ++_i; return *this; }
-  self& operator--() { --_i; return *this; }
-  self& operator+=(Distance n) { _i += n; return *this; }
-  self& operator-=(Distance n) { _i -= n; return *this; }
-  bool operator==(const self& x) const { return _i == x._i; }
-  bool operator<(const self& x) const { return _i < x._i; }
-  friend Distance operator-(const self& x, const self& y) {
-    return x._i - y._i; 
-  }
-protected:
-  T* _i;
-};
-
-

It has been compiled and run successfully with:

-
    -
  • GCC 2.95.2 -
  • Metrowerks Codewarrior 5.2 -
  • Microsoft Visual C++ 6.0 SP3
  • -
-

Jeremy Siek -contributed the iterator operators and helpers.  He also contributed iterators_test.cpp

-
-

Note for users of older versions

-

The changes in the library interface and recommended -usage were motivated by some practical issues described below. The new -version of the library is still backward-compatible with the former one (so -you're not forced change any existing code), but the old usage is -deprecated. Though it was arguably simpler and more intuitive than using base -class chaining, it has been discovered that the old practice of deriving -from multiple operator templates can cause the resulting classes to be much -larger than they should be. Most modern C++ compilers significantly bloat the -size of classes derived from multiple empty base classes, even though the base -classes themselves have no state. For instance, the size of point<int> -from the example above was 12-24 bytes on various compilers -for the Win32 platform, instead of the expected 8 bytes. -

Strictly speaking, it was not the library's fault - the language rules allow -the compiler to apply the empty base class optimization in that situation. In -principle an arbitrary number of empty base classes can be allocated at the same -offset, provided that none of them have a common ancestor (see section 10.5 [class.derived], -par. 5 of the standard). But the language definition also doesn't require -implementations to do the optimization, and few if any of today's compilers -implement it when multiple inheritance is involved. What's worse, it is very -unlikely that implementors will adopt it as a future enhancement to existing -compilers, because it would break binary compatibility between code generated by -two different versions of the same compiler. As Matt Austern said, "One of -the few times when you have the freedom to do this sort of thing is when you're -targeting a new architecture...". On the other hand, many common compilers -will use the empty base optimization for single inheritance hierarchies.

-

Given the importance of the issue for the users of the library (which aims to -be useful for writing light-weight classes like MyInt or point<>), -and the forces described above, we decided to change the library interface so -that the object size bloat could be eliminated even on compilers that support -only the simplest form of the empty base class optimization. The current library -interface is the result of those changes. Though the new usage is a bit more -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.

-
-

Revised 28 Sep 2000

-

© 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 -is" without express or implied warranty, and with no claim as to its -suitability for any purpose.

- - - - diff --git a/operators_test.cpp b/operators_test.cpp deleted file mode 100644 index a194521..0000000 --- a/operators_test.cpp +++ /dev/null @@ -1,481 +0,0 @@ -// Demonstrate and test boost/operators.hpp -------------------------------// - -// (C) Copyright Beman Dawes 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 -// 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) -// 12 Dec 99 Minor update, output confirmation message. -// 15 Nov 99 Initial version - -#include -#include -#include -#include - - -namespace -{ - // avoiding a template version of true_value so as to not confuse VC++ - int true_value(int x) { return x; } - long true_value(long x) { return x; } - signed char true_value(signed char 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; } - - // The use of operators<> here tended to obscure interactions with certain - // compiler bugs - template - class Wrapped1 : boost::operators > - { - public: - explicit Wrapped1( T v = T() ) : _value(v) {} - T value() const { return _value; } - - bool operator<(const Wrapped1& x) const { return _value < x._value; } - bool operator==(const Wrapped1& x) const { return _value == x._value; } - - 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/=(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&=(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; } - - private: - T _value; - }; - template - T true_value(Wrapped1 x) { return x.value(); } - - template - class Wrapped2 : - boost::operators >, - boost::operators2, U> - { - public: - explicit Wrapped2( T v = T() ) : _value(v) {} - T value() const { return _value; } - - bool operator<(const Wrapped2& x) const { return _value < x._value; } - bool operator==(const Wrapped2& x) const { return _value == x._value; } - - 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/=(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&=(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; } - - bool operator<(U u) const { return _value < u; } - bool operator>(U u) const { return _value > u; } - bool operator==(U u) const { return _value == u; } - Wrapped2& operator+=(U u) { _value += u; return *this; } - Wrapped2& operator-=(U u) { _value -= u; return *this; } - Wrapped2& operator*=(U u) { _value *= u; return *this; } - Wrapped2& operator/=(U u) { _value /= u; return *this; } - Wrapped2& operator%=(U u) { _value %= u; return *this; } - Wrapped2& operator|=(U u) { _value |= u; return *this; } - Wrapped2& operator&=(U u) { _value &= u; return *this; } - Wrapped2& operator^=(U u) { _value ^= u; return *this; } - - private: - T _value; - }; - template - T true_value(Wrapped2 x) { return x.value(); } - - // MyInt uses only the single template-argument form of all_operators<> - typedef Wrapped1 MyInt; - - typedef Wrapped2 MyLong; - - template - 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)); - } - - template - 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)); - } - - template - 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); - } - - template - void test_equality_comparable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2) - { - assert((x1 == y1) == (x2 == y2)); - assert((x1 != y1) == (x2 != y2)); - } - - template - 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); - } - - template - void test_multipliable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2) - { - assert((x1 * y1).value() == (x2 * y2)); - } - - template - 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); - } - - template - void test_addable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2) - { - assert((x1 + y1).value() == (x2 + y2)); - } - - template - 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); - } - - template - void test_subtractable(X1 x1, Y1 y1, X2 x2, Y2 y2) - { - sanity_check(x1, y1, x2, y2); - assert((x1 - y1).value() == x2 - y2); - } - - template - 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); - } - - template - 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); - } - - template - void test_xorable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2) - { - assert((x1 ^ y1).value() == (x2 ^ y2)); - } - - template - 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); - } - - template - void test_andable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2) - { - assert((x1 & y1).value() == (x2 & y2)); - } - - template - 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); - } - - template - void test_orable_aux(X1 x1, Y1 y1, X2 x2, Y2 y2) - { - assert((x1 | y1).value() == (x2 | y2)); - } - - template - void test_orable(X1 x1, Y1 y1, X2 x2, Y2 y2) - { - sanity_check(x1, y1, x2, y2); - test_orable_aux(x1, y1, x2, y2); - test_orable_aux(y1, x1, y2, x2); - } - - template - void test_incrementable(X1 x1, X2 x2) - { - sanity_check(x1, x1, x2, x2); - assert(x1++.value() == x2++); - assert(x1.value() == x2); - } - - template - void test_decrementable(X1 x1, X2 x2) - { - sanity_check(x1, x1, x2, x2); - assert(x1--.value() == x2--); - assert(x1.value() == x2); - } - - template - 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); - } - - template - struct tester - { - void operator()(boost::min_rand& randomizer) const - { - Big b1 = Big(randomizer()); - Big b2 = Big(randomizer()); - Small s = Small(randomizer()); - - test_all(Wrapped1(b1), Wrapped1(b2), b1, b2); - test_all(Wrapped2(b1), s, b1, s); - } - }; - - // added as a regression test. We had a bug which this uncovered. - struct Point - : boost::addable > - { - 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; } - - int h; - int v; - }; -} // unnamed namespace - - -// workaround for MSVC bug; for some reasons the compiler doesn't instantiate -// inherited operator templates at the moment it must, so the following -// explicit instantiations force it to do that. - -#if defined(BOOST_MSVC) && (_MSC_VER <= 1200) -template Wrapped1; -template Wrapped1; -template Wrapped1; -template Wrapped1; - -template Wrapped2; -template Wrapped2; -template Wrapped2; -template Wrapped2; -template Wrapped2; -template Wrapped2; -template Wrapped2; -template Wrapped2; -template Wrapped2; -template Wrapped2; -#endif - -#ifdef NDEBUG -#error This program is pointless when NDEBUG disables assert()! -#endif - -int main() -{ - // Regression test. - Point x; - x = x + Point(3, 4); - x = x - Point(3, 4); - - for (int n = 0; n < 10000; ++n) - { - boost::min_rand r; - tester()(r); - tester()(r); - tester()(r); - tester()(r); - tester()(r); - - tester()(r); - tester()(r); - tester()(r); - tester()(r); - tester()(r); - } - - MyInt i1(1); - MyInt i2(2); - MyInt i; - - assert( i1.value() == 1 ); - assert( i2.value() == 2 ); - assert( 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 ); - - 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 ); - - MyLong j1(1); - MyLong j2(2); - MyLong j; - - assert( j1.value() == 1 ); - assert( j2.value() == 2 ); - assert( 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 ); - - assert( (j1 + 2) == 3 ); - assert( (1 + j2) == 3 ); - j = j1 + j2; assert( j.value() == 3 ); - - assert( (j + 2) == 5 ); - assert( (3 + j2) == 5 ); - j = j + j2; assert( j.value() == 5 ); - - assert( (j - 1) == 4 ); - j = j - j1; assert( j.value() == 4 ); - - assert( (j * 2) == 8 ); - assert( (4 * j2) == 8 ); - j = j * j2; assert( j.value() == 8 ); - - assert( (j / 2) == 4 ); - j = j / j2; assert( j.value() == 4 ); - - assert( (j % 3) == 1 ); - j = j % (j - j1); assert( j.value() == 1 ); - - j = j2 + j2; assert( j.value() == 4 ); - - assert( (1 | j2 | j) == 7 ); - assert( (j1 | 2 | j) == 7 ); - assert( (j1 | j2 | 4) == 7 ); - j = j1 | j2 | j; assert( j.value() == 7 ); - - assert( (7 & j2) == 2 ); - assert( (j & 2) == 2 ); - j = j & j2; assert( j.value() == 2 ); - - j = j | j1; assert( j.value() == 3 ); - - assert( (3 ^ j1) == 2 ); - assert( (j ^ 1) == 2 ); - j = j ^ j1; assert( j.value() == 2 ); - - j = (j+j1)*(j2|j1); assert( j.value() == 9 ); - - std::cout << "0 errors detected\n"; - return 0; -} diff --git a/projection_iterator.htm b/projection_iterator.htm deleted file mode 100644 index a96fea0..0000000 --- a/projection_iterator.htm +++ /dev/null @@ -1,391 +0,0 @@ - - - - - - -Projection Iterator Adaptor Documentation - - - - -c++boost.gif (8819 bytes) - -

Projection Iterator Adaptor

- -Defined in header -boost/iterator_adaptors.hpp - -

-The projection iterator adaptor is similar to the transform iterator adaptor in that -its operator*() applies some function to the result of -dereferencing the base iterator and then returns the result. The -difference is that the function must return a reference to some -existing object (for example, a data member within the -value_type of the base iterator). The following -pseudo-code gives the basic idea. The data member p is -the function object. - -

-  reference projection_iterator::operator*() const {
-    return this->p(*this->base_iterator);
-  }
-
- -

Synopsis

- -
-namespace boost {
-  template <class AdaptableUnaryFunction, class BaseIterator>
-  struct projection_iterator_generator;
-  
-  template <class AdaptableUnaryFunction, 
-            class BaseIterator, class ConstBaseIterator>
-  struct projection_iterator_pair_generator;
-
-  template <class AdaptableUnaryFunction, class BaseIterator>
-  typename projection_iterator_generator<AdaptableUnaryFunction, BaseIterator>::type
-  make_projection_iterator(BaseIterator base,
-			   const AdaptableUnaryFunction& p = AdaptableUnaryFunction())
-
-  template <class AdaptableUnaryFunction, class ConstBaseIterator>
-  typename projection_iterator_generator<AdaptableUnaryFunction, ConstBaseIterator>::type
-  make_const_projection_iterator(ConstBaseIterator base,
-                                 const AdaptableUnaryFunction& p = AdaptableUnaryFunction())  
-}
-
- -
- -

The Projection Iterator Type -Generator

- -The class projection_iterator_generator is a helper class -whose purpose is to construct an projection iterator type. The main -template parameter for this class is the AdaptableUnaryFunction -function object type and the BaseIterator type that is being -wrapped. - -
-template <class AdaptableUnaryFunction, class BaseIterator>
-class projection_iterator_generator
-{
-public:
-  typedef iterator_adaptor<...> type; // the resulting projection iterator type 
-};
-
- -

Example

- -In the following example we have a list of personnel records. Each -record has an employee's name and ID number. We want to be able to -traverse through the list accessing either the name or the ID numbers -of the employees using the projection iterator so we create the -function object classes select_name and -select_ID. We then use the -projection_iterator_generator class to create a projection -iterator and use it to print out the names of the employees. - -
-#include <boost/config.hpp>
-#include <list>
-#include <iostream>
-#include <iterator>
-#include <algorithm>
-#include <string>
-#include <boost/iterator_adaptors.hpp>
-
-struct personnel_record {
-  personnel_record(std::string n, int id) : m_name(n), m_ID(id) { }
-  std::string m_name;
-  int m_ID;
-};
-
-struct select_name {
-  typedef personnel_record argument_type;
-  typedef std::string result_type;
-  const std::string& operator()(const personnel_record& r) const {
-    return r.m_name;
-  }
-  std::string& operator()(personnel_record& r) const {
-    return r.m_name;
-  }
-};
-
-struct select_ID {
-  typedef personnel_record argument_type;
-  typedef int result_type;
-  const int& operator()(const personnel_record& r) const {
-    return r.m_ID;
-  }
-  int& operator()(personnel_record& r) const {
-    return r.m_ID;
-  }
-};
-
-int main(int, char*[])
-{
-  std::list<personnel_record> personnel_list;
-
-  personnel_list.push_back(personnel_record("Barney", 13423));
-  personnel_list.push_back(personnel_record("Fred", 12343));
-  personnel_list.push_back(personnel_record("Wilma", 62454));
-  personnel_list.push_back(personnel_record("Betty", 20490));
-
-  // Example of using projection_iterator_generator
-  // to print out the names in the personnel list.
-
-  boost::projection_iterator_generator<select_name,
-    std::list<personnel_record>::iterator>::type
-    personnel_first(personnel_list.begin()),
-    personnel_last(personnel_list.end());
-
-  std::copy(personnel_first, personnel_last,
-            std::ostream_iterator<std::string>(std::cout, "\n"));
-  std::cout << std::endl;
-
-  // to be continued...
-
-The output for this part is: -
-Barney
-Fred
-Wilma
-Betty
-
- -

Template Parameters

- - - - - - - - - - - - - - - - - -
ParameterDescription
AdaptableUnaryFunctionThe type of the function object. The argument_type of the -function must match the value type of the base iterator. The function -should return a reference to the function's result_type. -The result_type will be the resulting iterator's value_type. -
BaseIteratorThe iterator type being wrapped.
- -

Model of

- -If the base iterator is a model of Random -Access Iterator then so is the resulting projection iterator. If -the base iterator supports less functionality than this the resulting -projection iterator will also support less functionality. - -

Members

- -The projection iterator type implements the member functions and -operators required of the Random -Access Iterator concept. -In addition it has the following constructor: - -
-projection_iterator_generator::type(const BaseIterator& it,
-                                    const AdaptableUnaryFunction& p = AdaptableUnaryFunction())
-
- -

-


-

- -

The Projection Iterator Pair -Generator

- -Sometimes a mutable/const pair of iterator types is needed, such as -when implementing a container type. The -projection_iterator_pair_generator class makes it more -convenient to create this pair of iterator types. - -
-template <class AdaptableUnaryFunction, class BaseIterator, class ConstBaseIterator>
-class projection_iterator_pair_generator
-{
-public:
-  typedef iterator_adaptor<...> iterator;       // the mutable projection iterator type 
-  typedef iterator_adaptor<...> const_iterator; // the immutable projection iterator type 
-};
-
- -

Example

- -In this part of the example we use the -projection_iterator_pair_generator to create a mutable/const -pair of projection iterators that access the ID numbers of the -personnel. We use the mutable iterator to re-index the ID numbers from -zero. We then use the constant iterator to print the ID numbers out. - -
-  // continuing from the last example...
-
-  typedef boost::projection_iterator_pair_generator<select_ID,
-    std::list<personnel_record>::iterator,
-    std::list<personnel_record>::const_iterator> PairGen;
-
-  PairGen::iterator ID_first(personnel_list.begin()),
-    ID_last(personnel_list.end());
-
-  int new_id = 0;
-  while (ID_first != ID_last) {
-    *ID_first = new_id++;
-    ++ID_first;
-  }
-
-  PairGen::const_iterator const_ID_first(personnel_list.begin()),
-    const_ID_last(personnel_list.end());
-
-  std::copy(const_ID_first, const_ID_last,
-            std::ostream_iterator<int>(std::cout, " "));
-  std::cout << std::endl;
-  std::cout << std::endl;
-  
-  // to be continued...
-
-0 1 2 3 
-
- -

Template Parameters

- - - - - - - - - - - - - - - - - - - - - - - -
ParameterDescription
AdaptableUnaryFunctionThe type of the function object. The argument_type of the -function must match the value type of the base iterator. The function -should return a true reference to the function's result_type. -The result_type will be the resulting iterator's value_type. -
BaseIteratorThe mutable iterator type being wrapped.
ConstBaseIteratorThe constant iterator type being wrapped.
- -

Model of

- -If the base iterator types model the Random -Access Iterator then so do the resulting projection iterator -types. If the base iterators support less functionality the -resulting projection iterator types will also support less -functionality. The resulting iterator type is mutable, and -the resulting const_iterator type is constant. - -

Members

- -The resulting iterator and const_iterator types -implements the member functions and operators required of the Random -Access Iterator concept. In addition they support the following -constructors: - -
-projection_iterator_pair_generator::iterator(const BaseIterator& it,
-                                             const AdaptableUnaryFunction& p = AdaptableUnaryFunction())
- -
-projection_iterator_pair_generator::const_iterator(const BaseIterator& it,
-                                                   const AdaptableUnaryFunction& p = AdaptableUnaryFunction())
-
- -

-


-

- -

The Projection Iterator Object Generators

- -The make_projection_iterator() and -make_const_projection_iterator() functions provide a more -convenient way to create projection iterator objects. The functions -save the user the trouble of explicitly writing out the iterator -types. - -
-template <class AdaptableUnaryFunction, class BaseIterator>
-typename projection_iterator_generator<AdaptableUnaryFunction, BaseIterator>::type
-make_projection_iterator(BaseIterator base,
-			 const AdaptableUnaryFunction& p = AdaptableUnaryFunction())  
-
-template <class AdaptableUnaryFunction, class ConstBaseIterator>
-typename projection_iterator_generator<AdaptableUnaryFunction, ConstBaseIterator>::type
-make_const_projection_iterator(ConstBaseIterator base,
-			       const AdaptableUnaryFunction& p = AdaptableUnaryFunction())  
-
- - -

Example

- -In this part of the example, we again print out the names of the -personnel, but this time we use the -make_const_projection_iterator() function to save some typing. - -
-  // continuing from the last example...
-
-  std::copy
-    (boost::make_const_projection_iterator<select_name>(personnel_list.begin()),
-     boost::make_const_projection_iterator<select_name>(personnel_list.end()),
-     std::ostream_iterator(std::cout, "\n"));
-
-  return 0;
-}
-
-The output is: -
-Barney
-Fred
-Wilma
-Betty
-
- -
-

Revised 10 Feb 2001

-

© 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" -without express or implied warranty, and with no claim as to its suitability for -any purpose.

- - - - - - - - diff --git a/projection_iterator_example.cpp b/projection_iterator_example.cpp deleted file mode 100644 index 5405ced..0000000 --- a/projection_iterator_example.cpp +++ /dev/null @@ -1,96 +0,0 @@ -// (C) Copyright Jeremy Siek 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. - -#include -#include -#include -#include -#include -#include -#include - -struct personnel_record { - personnel_record(std::string n, int id) : m_name(n), m_ID(id) { } - std::string m_name; - int m_ID; -}; - -struct select_name { - typedef personnel_record argument_type; - typedef std::string result_type; - const std::string& operator()(const personnel_record& r) const { - return r.m_name; - } - std::string& operator()(personnel_record& r) const { - return r.m_name; - } -}; - -struct select_ID { - typedef personnel_record argument_type; - typedef int result_type; - const int& operator()(const personnel_record& r) const { - return r.m_ID; - } - int& operator()(personnel_record& r) const { - return r.m_ID; - } -}; - -int main(int, char*[]) -{ - std::list personnel_list; - - personnel_list.push_back(personnel_record("Barney", 13423)); - personnel_list.push_back(personnel_record("Fred", 12343)); - personnel_list.push_back(personnel_record("Wilma", 62454)); - personnel_list.push_back(personnel_record("Betty", 20490)); - - // Example of using projection_iterator_generator - // to print out the names in the personnel list. - - boost::projection_iterator_generator::iterator>::type - personnel_first(personnel_list.begin()), - personnel_last(personnel_list.end()); - - std::copy(personnel_first, personnel_last, - std::ostream_iterator(std::cout, "\n")); - std::cout << std::endl; - - // Example of using projection_iterator_pair_generator - // to assign new ID numbers to the personnel. - - typedef boost::projection_iterator_pair_generator::iterator, - std::list::const_iterator> PairGen; - - PairGen::iterator ID_first(personnel_list.begin()), - ID_last(personnel_list.end()); - - int new_id = 0; - while (ID_first != ID_last) { - *ID_first = new_id++; - ++ID_first; - } - - PairGen::const_iterator const_ID_first(personnel_list.begin()), - const_ID_last(personnel_list.end()); - - std::copy(const_ID_first, const_ID_last, - std::ostream_iterator(std::cout, " ")); - std::cout << std::endl; - std::cout << std::endl; - - // Example of using make_const_projection_iterator() - // to print out the names in the personnel list again. - - std::copy - (boost::make_const_projection_iterator(personnel_list.begin()), - boost::make_const_projection_iterator(personnel_list.end()), - std::ostream_iterator(std::cout, "\n")); - - return 0; -} diff --git a/reverse_iterator.htm b/reverse_iterator.htm deleted file mode 100644 index f3c32d1..0000000 --- a/reverse_iterator.htm +++ /dev/null @@ -1,332 +0,0 @@ - - - - - - - - - - Reverse Iterator Adaptor Documentation - - - - c++boost.gif (8819 bytes) - -

Reverse Iterator Adaptor

- Defined in header boost/iterator_adaptors.hpp - -

The reverse iterator adaptor flips the direction of a base iterator's - motion. Invoking operator++() moves the base iterator backward and - invoking operator--() moves the base iterator forward. The Boost - reverse iterator adaptor is better to use than the - std::reverse_iterator class in situations where pairs of - mutable/constant iterators are needed (e.g., in containers) because - comparisons and conversions between the mutable and const versions are - implemented correctly. - -

Synopsis

-
-namespace boost {
-  template <class BidirectionalIterator,
-            class Value, class Reference, class Pointer, class Category, class Distance>
-  struct reverse_iterator_generator;
-  
-  template <class BidirectionalIterator>
-  typename reverse_iterator_generator<BidirectionalIterator>::type
-  make_reverse_iterator(BidirectionalIterator base)  
-}
-
-
- -

The Reverse Iterator Type - Generator

- The reverse_iterator_generator template is a generator of - reverse iterator types. The main template parameter for this class is the - base BidirectionalIterator type that is being adapted. In most - cases the associated types of the base iterator can be deduced using - std::iterator_traits, but in some situations the user may want to - override these types, so there are also template parameters for the base - iterator's associated types. - -
-
-template <class BidirectionalIterator,
-          class Value, class Reference, class Pointer, class Category, class Distance>
-class reverse_iterator_generator
-{
-public:
-  typedef iterator_adaptor<...> type; // the resulting reverse iterator type 
-};
-
-
- -

Example

- In this example we sort a sequence of letters and then output the sequence - in descending order using reverse iterators. - -
-
-#include <boost/config.hpp>
-#include <iostream>
-#include <algorithm>
-#include <boost/iterator_adaptors.hpp>
-
-int main(int, char*[])
-{
-  char letters[] = "hello world!";
-  const int N = sizeof(letters)/sizeof(char) - 1;
-  std::cout << "original sequence of letters:\t"
-      << letters << std::endl;
-
-  std::sort(letters, letters + N);
-
-  // Use reverse_iterator_generator to print a sequence
-  // of letters in reverse order.
-  
-  boost::reverse_iterator_generator<char*>::type
-    reverse_letters_first(letters + N),
-    reverse_letters_last(letters);
-
-  std::cout << "letters in descending order:\t";
-  std::copy(reverse_letters_first, reverse_letters_last,
-      std::ostream_iterator<char>(std::cout));
-  std::cout << std::endl;
-
-  // to be continued...
-
-
- The output is: - -
-
-original sequence of letters: hello world!
-letters in descending order:  wroolllhed! 
-
-
- -

Template Parameters

- - - - - - - - - -
Parameter - - Description - -
BidirectionalIterator - - - The iterator type being wrapped. - -
Value - - The value-type of the base iterator and the resulting reverse - iterator.
- Default:std::iterator_traits<BidirectionalIterator>::value_type - - -
Reference - - The reference type of the resulting iterator, and in - particular, the result type of operator*().
- Default: If Value is supplied, Value& is - used. Otherwise - std::iterator_traits<BidirectionalIterator>::reference - is used. - -
Pointer - - The pointer type of the resulting iterator, and in - particular, the result type of operator->().
- Default: If Value was supplied, then Value*, - otherwise - std::iterator_traits<BidirectionalIterator>::pointer. - -
Category - - The iterator_category type for the resulting iterator.
- Default: - std::iterator_traits<BidirectionalIterator>::iterator_category - - -
Distance - - The difference_type for the resulting iterator.
- Default: - std::iterator_traits<BidirectionalIterator&gt::difference_type - -
- -

Concept Model

- The indirect iterator will model whichever standard iterator concept - category is modeled by the base iterator. Thus, if the base iterator is - a model of Random Access - Iterator then so is the resulting indirect iterator. If the base - iterator models a more restrictive concept, the resulting indirect iterator - will model the same concept. The base iterator must be at least a Bidirectional - Iterator - -

Members

- The reverse iterator type implements the member functions and operators - required of the Random Access - Iterator concept. In addition it has the following constructor: - -
-
-reverse_iterator_generator::type(const BidirectionalIterator& it)
-
-
- - -
-
- -
- -

- -

The Reverse Iterator Object - Generator

- The make_reverse_iterator() function provides a more convenient - way to create reverse iterator objects. The function saves the user the - trouble of explicitly writing out the iterator types. - -
-
-template <class BidirectionalIterator>
-typename reverse_iterator_generator<BidirectionalIterator>::type
-make_reverse_iterator(BidirectionalIterator base);
-
-
- -

Example

- In this part of the example we use make_reverse_iterator() to - print the sequence of letters in reverse-reverse order, which is the - original order. - -
-
-  // continuing from the previous example...
-
-  std::cout << "letters in ascending order:\t";
-  std::copy(boost::make_reverse_iterator(reverse_letters_last),
-      boost::make_reverse_iterator(reverse_letters_first),
-      std::ostream_iterator<char>(std::cout));
-  std::cout << std::endl;
-
-  return 0;
-}
-
-
- The output is: - -
-
-letters in ascending order:  !dehllloorw
-
-
-
- -

Constant/Mutable Iterator Interactions

- -

One failing of the standard reverse_iterator - adaptor is that it doesn't properly support interactions between adapted - const and non-const iterators. For example: -

-
-#include <vector>
-
-template <class T> void convert(T x) {}
-
-// Test interactions of a matched pair of random access iterators
-template <class Iterator, class ConstIterator>
-void test_interactions(Iterator i, ConstIterator ci)
-{
-  bool eq = i == ci;               // comparisons
-  bool ne = i != ci;            
-  bool lt = i < ci;
-  bool le = i <= ci;
-  bool gt = i > ci;
-  bool ge = i >= ci;
-  std::size_t distance = i - ci;   // difference
-  ci = i;                          // assignment
-  ConstIterator ci2(i);            // construction
-  convert<ConstIterator>(i);       // implicit conversion
-}
-
-void f()
-{
-  typedef std::vector<int> vec;
-  vec v;
-  const vec& cv;
-
-  test_interactions(v.begin(), cv.begin());   // OK
-  test_interactions(v.rbegin(), cv.rbegin()); // ERRORS ON EVERY TEST!!
-
-
-Reverse iterators created with boost::reverse_iterator_generator don't have this problem, though: -
-
-  typedef boost::reverse_iterator_generator<vec::iterator>::type ri;
-  typedef boost::reverse_iterator_generator<vec::const_iterator>::type cri;
-  test_interactions(ri(v.begin()), cri(cv.begin()));   // OK!!
-
-
-Or, more simply, -
-
-  test_interactions(
-    boost::make_reverse_iterator(v.begin()), 
-    boost::make_reverse_iterator(cv.begin()));   // OK!!
-}
-
-
- -

If you are wondering why there is no -reverse_iterator_pair_generator in the manner of projection_iterator_pair_generator, -the answer is simple: we tried it, but found that in practice it took -more typing to use reverse_iterator_pair_generator than to -simply use reverse_iterator_generator twice!

- -


- - -

Revised - 15 - Feb 2001 - - -

© 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" without express or - implied warranty, and with no claim as to its suitability for any purpose. - - - - - - - diff --git a/reverse_iterator_example.cpp b/reverse_iterator_example.cpp deleted file mode 100644 index 40c859f..0000000 --- a/reverse_iterator_example.cpp +++ /dev/null @@ -1,42 +0,0 @@ -// (C) Copyright Jeremy Siek 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. - -#include -#include -#include -#include - -int main(int, char*[]) -{ - char letters[] = "hello world!"; - const int N = sizeof(letters)/sizeof(char) - 1; - std::cout << "original sequence of letters:\t" - << letters << std::endl; - - std::sort(letters, letters + N); - - // Use reverse_iterator_generator to print a sequence - // of letters in reverse order. - - boost::reverse_iterator_generator::type - reverse_letters_first(letters + N), - reverse_letters_last(letters); - - std::cout << "letters in descending order:\t"; - std::copy(reverse_letters_first, reverse_letters_last, - std::ostream_iterator(std::cout)); - std::cout << std::endl; - - // Use make_reverse_iterator() to print the sequence - // of letters in reverse-reverse order. - - std::cout << "letters in ascending order:\t"; - std::copy(boost::make_reverse_iterator(reverse_letters_last), - boost::make_reverse_iterator(reverse_letters_first), - std::ostream_iterator(std::cout)); - std::cout << std::endl; - - return 0; -} diff --git a/tie.html b/tie.html deleted file mode 100644 index 8023b61..0000000 --- a/tie.html +++ /dev/null @@ -1,137 +0,0 @@ - - - -Boost Tie - -C++ Boost - -
- -

-tie -

- -

-

-template <class A, class B>
-tied<A,B> tie(A& a, B& b);
-
- -

-This is a utility function that makes it more convenient to work with -a function which returns a std::pair<>. The effect of the tie() -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 [1]. - -

- -

Where Defined

- -

-boost/utility.hpp - -

- -

Example

- -

-An example of using the tie() function with the -vertices() function, which returns a pair of -type std::pair<vertex_iterator,vertex_iterator>. The -pair of iterators is assigned to the iterator variables i and -end. - -

-

-  graph_traits< adjacency_list<> >::vertex_iterator i, end;
-  for(tie(i,end) = vertices(G); i != end; ++i)
-    // ...
-
- -

-Here is another example that uses tie() for handling operations with std::set. - -

-

-#include <set>
-#include <algorithm>
-#include <iostream>
-#include <boost/utility.hpp>
-
-int
-main(int, char*[])
-{
-  {
-    typedef std::set<int> SetT;
-    SetT::iterator i, end;
-    bool inserted;
-    
-    int vals[5] = { 5, 2, 4, 9, 1 };
-    SetT s(vals, vals + 5);
-    
-    // Using tie() with a return value of pair<iterator,bool>
-
-    int new_vals[2] = { 3, 9 };
-
-    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;
-      else
-        std::cout << *i << " successfully inserted." << std::endl;    
-    }
-  }    
-  {
-    int* i, *end;
-    int vals[6] = { 5, 2, 4, 4, 9, 1 };
-    std::sort(vals, vals + 6);
-
-    // 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;
-    // Footnote: of course one would normally just use std::count()
-    // to get this information, but that would spoil the example :)
-  }
-  return 0;
-}
-
-The output is: -
-  3 successfully inserted.
-  9 was already in the set.
-  There were 2 occurrences of 4.
-
- -
-
- - -
Copyright © 2000 -Jeremy Siek, -Univ.of Notre Dame (jsiek@lsc.nd.edu)
-Lie-Quan Lee, Univ.of Notre Dame (llee1@lsc.nd.edu)
-Andrew Lumsdaine, -Univ.of Notre Dame (lums@lsc.nd.edu) -
- - - diff --git a/tie_example.cpp b/tie_example.cpp deleted file mode 100644 index 54a81af..0000000 --- a/tie_example.cpp +++ /dev/null @@ -1,61 +0,0 @@ -// (C) Copyright Jeremy Siek 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. -// -// This is an example demonstrating how to use the tie() function. -// The purpose of tie() is to make it easiery to deal with std::pair -// return values. -// -// Contributed by Jeremy Siek -// -// Sample output -// -// 3 successfully inserted. -// 9 was already in the set. -// There were 2 occurances of 4. - -#include -#include -#include -#include - -int -main(int, char*[]) -{ - { - typedef std::set SetT; - SetT::iterator i, end; - bool inserted; - - int vals[5] = { 5, 2, 4, 9, 1 }; - SetT s(vals, vals + 5); - - // Using tie() with a return value of pair - - int new_vals[2] = { 3, 9 }; - - 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; - else - std::cout << *i << " successfully inserted." << std::endl; - } - } - { - int* i, *end; - int vals[6] = { 5, 2, 4, 4, 9, 1 }; - std::sort(vals, vals + 6); - - // Using tie() with a return value of pair - - boost::tie(i,end) = std::equal_range(vals, vals + 6, 4); - 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 :) - } - return 0; -} diff --git a/transform_iterator.htm b/transform_iterator.htm deleted file mode 100644 index 63cecb1..0000000 --- a/transform_iterator.htm +++ /dev/null @@ -1,215 +0,0 @@ - - - - - - -Transform Iterator Adaptor Documentation - - - - -c++boost.gif (8819 bytes) - -

Transform Iterator Adaptor

- -Defined in header -boost/iterator_adaptors.hpp - -

-The transform iterator adaptor augments an iterator by applying some -function object to the result of dereferencing the iterator. Another -words, the operator* of the transform iterator first -dereferences the base iterator, passes the result of this to the -function object, and then returns the result. The following -pseudo-code shows the basic idea: - -

-  value_type transform_iterator::operator*() const {
-    return this->f(*this->base_iterator);
-  }
-
- -All of the other operators of the transform iterator behave in the -same fashion as those of the base iterator. - - -

Synopsis

- -
-namespace boost {
-  template <class AdaptableUnaryFunction, class BaseIterator>
-  class transform_iterator_generator;
-
-  template <class AdaptableUnaryFunction, class BaseIterator>
-  typename transform_iterator_generator<AdaptableUnaryFunction,Iterator>::type
-  make_transform_iterator(BaseIterator base, const AdaptableUnaryFunction& f = AdaptableUnaryFunction());
-}
-
- -
- -

The Transform Iterator Type -Generator

- -The class transform_iterator_generator is a helper class whose -purpose is to construct a transform iterator type. The template -parameters for this class are the AdaptableUnaryFunction function object -type and the BaseIterator type that is being wrapped. - -
-template <class AdaptableUnaryFunction, class Iterator>
-class transform_iterator_generator
-{
-public:
-    typedef iterator_adaptor<...> type;
-};
-
- -

Example

- -

-The following is an example of how to use the -transform_iterator_generator class to iterate through a range of -numbers, multiplying each of them by 2 when they are dereferenced. - -

-

-#include <functional>
-#include <iostream>
-#include <boost/iterator_adaptors.hpp>
-
-int
-main(int, char*[])
-{
-  int x[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
-
-  typedef std::binder1st< std::multiplies<int> > Function;
-  typedef boost::transform_iterator_generator<Function, int*>::type doubling_iterator;
-
-  doubling_iterator i(x, std::bind1st(std::multiplies<int>(), 2)),
-    i_end(x + sizeof(x)/sizeof(int), std::bind1st(std::multiplies<int>(), 2));
-
-  std::cout << "multiplying the array by 2:" << std::endl;
-  while (i != i_end)
-    std::cout << *i++ << " ";
-  std::cout << std::endl;
-
-  // to be continued...
-
-The output from this part is: -
-2 4 6 8 10 12 14 16
-
- -

Template Parameters

- - - - - - - - - - - - - - - - -
ParameterDescription
AdaptableUnaryFunctionThe function object that transforms each element in the iterator -range. The argument_type of the function object must match -the value type of the base iterator. The result_type of the -function object will be the resulting iterator's -value_type. If you want the resulting iterator to behave as -an iterator, the result of the function should be solely a function of -its argument.
BaseIteratorThe iterator type being wrapped. This type must at least be a model - of the InputIterator concept.
- -

Model of

- -The transform iterator adaptor (the type -transform_iterator_generator<...>::type) is a model of Input Iterator[1]. - - -

Members

- -The transform iterator type implements the member functions and -operators required of the Random Access Iterator -concept, except that the reference type is the same as the value_type -so operator*() returns by-value. In addition it has the following constructor: - -
-transform_iterator_generator::type(const BaseIterator& it,
-                                   const AdaptableUnaryFunction& f = AdaptableUnaryFunction())
-
- -

-


-

- - -

The Transform Iterator Object Generator

- -
-template <class AdaptableUnaryFunction, class BaseIterator>
-typename transform_iterator_generator<AdaptableUnaryFunction,BaseIterator>::type
-make_transform_iterator(BaseIterator base,
-                        const AdaptableUnaryFunction& f = AdaptableUnaryFunction());
-
- -This function provides a convenient way to create transform iterators. - -

Example

- -Continuing from the previous example, we use the make_transform_iterator() -function to add four to each element of the array. - -
-  std::cout << "adding 4 to each element in the array:" << std::endl;
-
-  std::copy(boost::make_transform_iterator(x, std::bind1st(std::plus(), 4)),
-	    boost::make_transform_iterator(x + N, std::bind1st(std::plus(), 4)),
-	    std::ostream_iterator(std::cout, " "));
-  std::cout << std::endl;
-
-  return 0;
-}
-
-The output from this part is: -
-5 6 7 8 9 10 11 12
-
- -

Notes

- - -[1] If the base iterator is a model of Random Access Iterator -then the transform iterator will also suppport most of the -functionality required by the Random Access Iterator concept. However, a -transform iterator can never completely satisfy the requirements for -Forward Iterator -(or of any concepts that refine Forward Iterator, which includes -Random Access Iterator and Bidirectional Iterator) since the operator* of the transform -iterator always returns by-value. - - - -
-

Revised 10 Feb 2001

-

© 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" -without express or implied warranty, and with no claim as to its suitability for -any purpose.

- - - - diff --git a/transform_iterator_example.cpp b/transform_iterator_example.cpp deleted file mode 100644 index 4876e0c..0000000 --- a/transform_iterator_example.cpp +++ /dev/null @@ -1,44 +0,0 @@ -// (C) Copyright Jeremy Siek 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. - - -#include -#include -#include -#include - -int -main(int, char*[]) -{ - // This is a simple example of using the transform_iterators class to - // generate iterators that multiply the value returned by dereferencing - // the iterator. In this case we are multiplying by 2. - // Would be cooler to use lambda library in this example. - - int x[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; - const int N = sizeof(x)/sizeof(int); - - typedef std::binder1st< std::multiplies > Function; - typedef boost::transform_iterator_generator::type doubling_iterator; - - doubling_iterator i(x, std::bind1st(std::multiplies(), 2)), - i_end(x + N, std::bind1st(std::multiplies(), 2)); - - std::cout << "multiplying the array by 2:" << std::endl; - while (i != i_end) - std::cout << *i++ << " "; - std::cout << std::endl; - - std::cout << "adding 4 to each element in the array:" << std::endl; - - std::copy(boost::make_transform_iterator(x, std::bind1st(std::plus(), 4)), - boost::make_transform_iterator(x + N, std::bind1st(std::plus(), 4)), - std::ostream_iterator(std::cout, " ")); - std::cout << std::endl; - - return 0; -} - - diff --git a/utility.htm b/utility.htm deleted file mode 100644 index 7b477ce..0000000 --- a/utility.htm +++ /dev/null @@ -1,104 +0,0 @@ - - - - -Header boost/utility.hpp Documentation - - - - -

c++boost.gif (8819 bytes)Header -boost/utility.hpp

- -

The entire contents of the header <boost/utility.hpp> - are in namespace boost.

- -

Contents

- - -

Function templates next() and prior()

- -

Certain data types, such as the C++ Standard Library's forward and -bidirectional iterators, do not provide addition and subtraction via operator+() -or operator-().  This means that non-modifying computation of the next or -prior value requires a temporary, even though operator++() or operator--() is -provided.  It also means that writing code like itr+1 inside a -template restricts the iterator category to random access iterators.

- -

The next() and prior() functions provide a simple way around these problems:

- -
- -
template <class T>
-T next(T x) { return ++x; }
-
-template <class X>
-T prior(T x) { return --x; }
- -
- -

Usage is simple:

- -
- -
const std::list<T>::iterator p = get_some_iterator();
-const std::list<T>::iterator prev = boost::prior(p);
- -
- -

Contributed by Dave Abrahams.

- -

Class noncopyable

- -

Class noncopyable is a base class.  Derive your own class from noncopyable -when you want to prohibit copy construction and copy assignment.

- -

Some objects, particularly those which hold complex resources like files or -network connections, have no sensible copy semantics.  Sometimes there are -possible copy semantics, but these would be of very limited usefulness and be -very difficult to implement correctly.  Sometimes you're implementing a class that doesn't need to be copied -just yet and you don't want to take the time to write the appropriate functions.  -Deriving from noncopyable will prevent the otherwise implicitly-generated -functions (which don't have the proper semantics) from becoming a trap for other programmers.

- -

The traditional way to deal with these is to declare a private copy constructor and copy assignment, and then -document why this is done.  But deriving from noncopyable is simpler -and clearer, and doesn't require additional documentation.

- -

The program noncopyable_test.cpp can be -used to verify class noncopyable works as expected. It has have been run successfully under -GCC 2.95, Metrowerks -CodeWarrior 5.0, and Microsoft Visual C++ 6.0 sp 3.

- -

Contributed by Dave Abrahams.

- -

Example

-
-
// inside one of your own headers ...
-#include <boost/utility.hpp>
-
-class ResourceLadenFileSystem : boost::noncopyable {
-...
-
- -

Rationale

-

Class noncopyable has protected constructor and destructor members to -emphasize that it is to be used only as a base class.  Dave Abrahams notes -concern about the effect on compiler optimization of adding (even trivial inline) -destructor declarations. He says "Probably this concern is misplaced, because -noncopyable will be used mostly for classes which own resources and thus have non-trivial destruction semantics."

-
-

Revised  28 September, 2000 -

-

© Copyright boost.org 1999. 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" without express or -implied warranty, and with no claim as to its suitability for any purpose.

- -