diff --git a/Assignable.html b/Assignable.html deleted file mode 100644 index 54934f1..0000000 --- a/Assignable.html +++ /dev/null @@ -1,109 +0,0 @@ - - - -
- - - -A type is Assignable if it is possible to assign one object of the type - to another object of that type.
- -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 | -
Name | - -Expression | - -Return type | - -Semantics | -
---|---|---|---|
Assignment | - -t = u | - -T& | - -t is equivalent to u | -
DefaultConstructible
- and CopyConstructible
Revised - 05 December, 2006
- -Copyright © 2000 | - -Jeremy Siek, Univ.of - Notre Dame (jsiek@lsc.nd.edu) | -
Distributed under the Boost Software License, Version 1.0. (See - accompanying file LICENSE_1_0.txt or - copy at http://www.boost.org/LICENSE_1_0.txt)
- - diff --git a/Collection.html b/Collection.html deleted file mode 100644 index c811e7e..0000000 --- a/Collection.html +++ /dev/null @@ -1,534 +0,0 @@ - - - - - - - -A Collection is a concept similar to the STL Container concept. A - Collection provides iterators for accessing a range of elements and - provides information about the number of elements in the Collection. - However, a Collection has fewer requirements than a Container. The - motivation for the Collection concept is that there are many useful - Container-like types that do not meet the full requirements of Container, - and many algorithms that can be written with this reduced set of - requirements. To summarize the reduction in requirements:
- -Value type | - -X::value_type | - -The type of the object stored in a Collection. If the - Collection is mutable then the value type must be Assignable. Otherwise - the value type must be CopyConstructible. | -
Iterator type | - -X::iterator | - -The type of iterator used to iterate through a - Collection's elements. The iterator's value type is expected to be the - Collection's value type. A conversion from the iterator type to the - const iterator type must exist. The iterator type must be an InputIterator. | -
Const iterator type | - -X::const_iterator | - -A type of iterator that may be used to examine, but - not to modify, a Collection's elements. | -
Reference type | - -X::reference | - -A type that behaves like a reference to the - Collection's value type. [1] | -
Const reference type | - -X::const_reference | - -A type that behaves like a const reference to the - Collection's value type. | -
Pointer type | - -X::pointer | - -A type that behaves as a pointer to the Collection's - value type. | -
Distance type | - -X::difference_type | - -A signed integral type used to represent the distance - between two of the Collection's iterators. This type must be the same - as the iterator's distance type. | -
Size type | - -X::size_type | - -An unsigned integral type that can represent any - nonnegative value of the Collection's distance type. | -
X | - -A type that is a model of Collection. | -
a, b | - -Object of type X. | -
T | - -The value type of X. | -
The following expressions must be valid.
- -Name | - -Expression | - -Return type | -
---|---|---|
Beginning of range | - -a.begin() | - -iterator if a is mutable, - const_iterator otherwise | -
End of range | - -a.end() | - -iterator if a is mutable, - const_iterator otherwise | -
Size | - -a.size() | - -size_type | -
Empty Collection | - -a.empty() | - -Convertible to bool | -
Swap | - -a.swap(b) | - -void | -
Name | - -Expression | - -Semantics | - -Postcondition | -
---|---|---|---|
Beginning of range | - -a.begin() | - -Returns an iterator pointing to the first element in - the Collection. | - -a.begin() is either dereferenceable or - past-the-end. It is past-the-end if and only if a.size() == - 0. | -
End of range | - -a.end() | - -Returns an iterator pointing one past the last element - in the Collection. | - -a.end() is past-the-end. | -
Size | - -a.size() | - -Returns the size of the Collection, that is, its - number of elements. | - -a.size() >= 0 | -
Empty Collection | - -a.empty() | - -Equivalent to a.size() == 0. (But possibly - faster.) | - -- |
Swap | - -a.swap(b) | - -Equivalent to swap(a,b) | - -- |
begin() and end() are amortized constant time.
- -size() is at most linear in the Collection's size. - empty() is amortized constant time.
- -swap() is at most linear in the size of the two - collections.
- -Valid range | - -For any Collection a, [a.begin(), - a.end()) is a valid range. | -
Range size | - -a.size() is equal to the distance from - a.begin() to a.end(). | -
Completeness | - -An algorithm that iterates through the range - [a.begin(), a.end()) will pass through every element of - a. | -
There are quite a few concepts that refine the Collection concept, - similar to the concepts that refine the Container concept. Here is a brief - overview of the refining concepts.
- -The elements are arranged in some order that does not change - spontaneously from one iteration to the next. As a result, a - ForwardCollection is EqualityComparable - and LessThanComparable. - In addition, the iterator type of a ForwardCollection is a - MultiPassInputIterator which is just an InputIterator with the added - 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 ForwardCollection also - has a front() method.
- -Name | - -Expression | - -Return type | - -Semantics | -
---|---|---|---|
Front | - -a.front() | - -reference if a is mutable, - const_reference otherwise. |
-
- Equivalent to *(a.begin()). | -
The container provides access to iterators that traverse in both - directions (forward and reverse). The iterator type must meet all of the - requirements of BidirectionalIterator - except that the reference type does not have to be a real C++ reference. - The ReversibleCollection adds the following requirements to those of - ForwardCollection.
- -Name | - -Expression | - -Return type | - -Semantics | -
---|---|---|---|
Beginning of range | - -a.rbegin() | - -reverse_iterator if a is mutable, - const_reverse_iterator otherwise. | - -Equivalent to - X::reverse_iterator(a.end()). | -
End of range | - -a.rend() | - -reverse_iterator if a is mutable, - const_reverse_iterator otherwise. | - -Equivalent to - X::reverse_iterator(a.begin()). | -
Back | - -a.back() | - -reference if a is mutable, - const_reference otherwise. |
-
- Equivalent to *(--a.end()). | -
The elements are arranged in a strict linear order. No extra methods are - required.
- -The iterators of a RandomAccessCollection satisfy all of the - requirements of RandomAccessIterator - except that the reference type does not have to be a real C++ reference. In - addition, a RandomAccessCollection provides an element access operator.
- -Name | - -Expression | - -Return type | - -Semantics | -
---|---|---|---|
Element Access | - -a[n] | - -reference if a is mutable, - const_reference otherwise. | - -Returns the nth element of the Collection. n - must be convertible to size_type. Precondition: 0 <= n - < a.size(). | -
[1] The reference type does not have to be a - real C++ reference. The requirements of the reference type depend on the - context within which the Collection is being used. Specifically it depends - on the requirements the context places on the value type of the Collection. - The reference type of the Collection must meet the same requirements as the - value type. In addition, the reference objects must be equivalent to the - value type objects in the collection (which is trivially true if they are - the same object). Also, in a mutable Collection, an assignment to the - reference object must result in an assignment to the object in the - Collection (again, which is trivially true if they are the same object, but - non-trivial if the reference type is a proxy class).
- -Revised - 05 - December, 2006
- -Copyright © 2000 | - -Jeremy - Siek, Univ.of Notre Dame and C++ Library & Compiler Group/SGI - (jsiek@engr.sgi.com) | -
Distributed under the Boost Software License, Version 1.0. (See - accompanying file LICENSE_1_0.txt or - copy at http://www.boost.org/LICENSE_1_0.txt)
- - diff --git a/CopyConstructible.html b/CopyConstructible.html deleted file mode 100644 index 40ff7a7..0000000 --- a/CopyConstructible.html +++ /dev/null @@ -1,185 +0,0 @@ - - - - - - - -A type is Copy Constructible if it is possible to copy objects of that - type.
- -T | - -is type that is a model of Copy Constructible | -
t | - -is an object of type T | -
u | - -is an object of type const T | -
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 | -
- 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; - }; -- -
Default
- Constructible and Assignable
Revised - 05 - December, 2006
- -Copyright © 2000 | - -Jeremy Siek, Univ.of - Notre Dame (jsiek@lsc.nd.edu) | -
Distributed under the Boost Software License, Version 1.0. (See - accompanying file LICENSE_1_0.txt or - copy at http://www.boost.org/LICENSE_1_0.txt)
- - diff --git a/LessThanComparable.html b/LessThanComparable.html deleted file mode 100644 index a723377..0000000 --- a/LessThanComparable.html +++ /dev/null @@ -1,210 +0,0 @@ - - - - - - - - - -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.
- -X | - -A type that is a model of LessThanComparable | -
x, y, z | - -Object of type X | -
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.
- -Name | - -Expression | - -Type requirements | - -Return type | -
---|---|---|---|
Less | - -x < y | - -- - | Convertible to bool | -
Name | - -Expression | - -Precondition | - -Semantics | - -Postcondition | -
---|---|---|---|---|
Less | - -x < y | - -x and y are in the domain of - < | - -- |
Irreflexivity | - -x < x must be false. | -
Antisymmetry | - -x < y implies !(y < x) [2] | -
Transitivity | - -x < y and y < z implies x - < z [3] | -
[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.
- -EqualityComparable,
- StrictWeakOrdering
-
Revised - 05 - December, 2006
- -Copyright © 2000 | - -Jeremy Siek, Univ.of - Notre Dame (jsiek@lsc.nd.edu) | -
Distributed under the Boost Software License, Version 1.0. (See - accompanying file LICENSE_1_0.txt or - copy at http://www.boost.org/LICENSE_1_0.txt)
- - diff --git a/MultiPassInputIterator.html b/MultiPassInputIterator.html deleted file mode 100644 index fa7517c..0000000 --- a/MultiPassInputIterator.html +++ /dev/null @@ -1,95 +0,0 @@ - - - - - - - -This concept is a refinement of Input Iterator, 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 Multi-Pass Input Iterator - is very similar to the Forward Iterator. - The only difference is that a Forward Iterator - requires the reference type to be value_type&, - whereas MultiPassInputIterator is like Input Iterator in that - the reference type merely has to be convertible to - value_type.
- -comments by Valentin Bonnard:
- -I think that introducing Multi-Pass Input Iterator isn't the right - solution. Do you also want to define Multi-Pass Bidirectionnal Iterator and - Multi-Pass Random Access Iterator ? 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 Random Access 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 Multi-Pass Input Iterator is just called a Forward - Iterator.
- -Other translations are:
- std::Forward Iterator -> ForwardIterator & Lvalue Iterator
- std::Bidirectionnal Iterator -> Bidirectionnal Iterator & Lvalue
- Iterator
- std::Random Access Iterator -> Random Access Iterator & Lvalue
- Iterator
Note that in practice the only operation not allowed on my Forward - Iterator which is allowed on std::Forward Iterator 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 Forward Iterator. The right course of action
- is to get Forward Iterator, etc. changed in the C++ standard. Once that is
- done we can drop Multi-Pass Input Iterator.
Revised - 05 - December, 2006
- -Copyright © 2000 | - -Jeremy Siek, Univ.of - Notre Dame (jsiek@lsc.nd.edu) | -
Distributed under the Boost Software License, Version 1.0. (See - accompanying file LICENSE_1_0.txt or - copy at http://www.boost.org/LICENSE_1_0.txt)
- - diff --git a/OptionalPointee.html b/OptionalPointee.html deleted file mode 100644 index a6d6d97..0000000 --- a/OptionalPointee.html +++ /dev/null @@ -1,158 +0,0 @@ - - -T | -is a type that is a model of OptionalPointee | -
t | -is an object of type T or possibly const T | -
Name | -Expression | -Return type | -Semantics | -|
---|---|---|---|---|
Value Access | -*t | -T& | -If the pointee is valid returns a reference to
- the pointee. - If the pointee is invalid the result is undefined. |
- - |
Value Access | -t->xyz | -T* | -If the pointee is valid returns a builtin pointer to the pointee. - If the pointee is invalid the result is undefined (It might not even return NULL). - |
- - |
Validity Test | - t - t != 0 - !!t - |
- bool | -If the pointee is valid returns true. - If the pointee is invalid returns false. |
- - |
Invalidity Test | - t == 0 - !t - |
- bool | -If the pointee is valid returns false. - If the pointee is invalid returns true. |
- - |
This concept does not define any particular semantic for relational operations, therefore,
-a type which models this concept might have either shallow or deep relational semantics.
-For instance, pointers, which are models of OptionalPointee, have shallow relational operators:
-comparisons of pointers do not involve comparisons of pointees.
-This makes sense for pointers because they have shallow copy semantics.
-But boost::optional<T>, on the other hand, which is also a model of OptionalPointee, has
-deep-copy and deep-relational semantics.
-If generic code is written for this concept, it is important not to use relational
-operators directly because the semantics might be different depending on the actual type.
-Still, the concept itsef can be used to define deep relational tests that can
-be used in generic code with any type which models OptionalPointee:
Equivalence relation:
-template<class OptionalPointee> -inline -bool equal_pointees ( OptionalPointee const& x, OptionalPointee const& y ) -{ - return (!x) != (!y) ? false : ( !x ? true : (*x) == (*y) ) ; -} -template<class OptionalPointee> -struct equal_pointees_t : std::binary_function<OptionalPointee,OptionalPointee,bool> -{ - bool operator() ( OptionalPointee const& x, OptionalPointee const& y ) const - { return equal_pointees(x,y) ; } -} ; --
The preceding generic function and function object have the following semantics:
-If both x and y have valid pointees, it compares values via (*x == *y)
.
-If only one has a valid pointee, returns false
.
-If both have invalid pointees, returns true
.
Less-than relation:
-template<class OptionalPointee> -inline -bool less_pointees ( OptionalPointee const& x, OptionalPointee const& y ) -{ - return !y ? false : ( !x ? true : (*x) < (*y) ) ; -} -template<class OptionalPointee> -struct less_pointees_t : std::binary_function<OptionalPointee,OptionalPointee,bool> -{ - bool operator() ( OptionalPointee const& x, OptionalPointee const& y ) const - { return less_pointees(x,y) ; } -} ; --
The preceding generic function and function object have the following semantics:
-If y has an invalid pointee, returns false
.
-Else, if x has an invalid pointee, returns true
.
-Else, ( x and y have valid pointees), compares values via (*x <
-*y).
-All these functions and function
-objects are is implemented in compare_pointees.hpp
Notice that OptionalPointee does not imply aliasing (and optional<> for instance does not alias); -so direct usage of relational operators with the implied aliasing of shallow semantics --as with pointers- should not be used with generic code written for this concept.
- -Copyright © 2003 | -Fernando Cacciola, -based on the original concept developed by Augustus Saunders. - |
![]() |
-
- assert.hpp- |
-
- |
- The header <boost/assert.hpp> defines the macro BOOST_ASSERT, - which is similar to the standard assert macro defined in <cassert>. - The macro is intended to be used in Boost libraries. -
-By default, BOOST_ASSERT(expr) is equivalent to assert(expr).
-When the macro BOOST_DISABLE_ASSERTS is defined when <boost/assert.hpp> - is included, BOOST_ASSERT(expr) is defined as ((void)0). This - allows users to selectively disable BOOST_ASSERT without - affecting the definition of the standard assert.
-When the macro BOOST_ENABLE_ASSERT_HANDLER is defined when <boost/assert.hpp> - is included, BOOST_ASSERT(expr) evaluates expr and, if the - result is false, evaluates the expression
-::boost::assertion_failed(#expr, BOOST_CURRENT_FUNCTION, - __FILE__, __LINE__)
-assertion_failed is declared in <boost/assert.hpp> - as
--namespace boost -{ - -void assertion_failed(char const * expr, char const * function, char const * file, long line); - -} --
but it is never defined. The user is expected to supply an appropriate - definition.
-As is the case with <cassert>, <boost/assert.hpp> - can be included multiple times in a single translation unit. BOOST_ASSERT - will be redefined each time as specified above.
-
- Copyright © 2002 by Peter Dimov. Distributed under the Boost Software License, Version
- 1.0. See accompanying file LICENSE_1_0.txt or
- copy at http://www.boost.org/LICENSE_1_0.txt.
The class template boost::base_from_member
provides
-a workaround for a class that needs to initialize a base class with a
-member. The class template is in boost/utility/base_from_member.hpp
-which is included in boost/utility.hpp.
There is test/example code in base_from_member_test.cpp.
- -When developing a class, sometimes a base class needs to be -initialized with a member of the current class. As a naïve -example:
- -- --#include <streambuf> // for std::streambuf -#include <ostream> // for std::ostream - -class fdoutbuf - : public std::streambuf -{ -public: - explicit fdoutbuf( int fd ); - //... -}; - -class fdostream - : public std::ostream -{ -protected: - fdoutbuf buf; -public: - explicit fdostream( int fd ) - : buf( fd ), std::ostream( &buf ) - {} - //... -}; -
This is undefined because C++'s initialization order mandates that -the base class is initialized before the member it uses. R. Samuel Klatchko developed a way -around this by using the initialization order in his favor. Base -classes are intialized in order of declaration, so moving the desired -member to another base class, that is initialized before the desired -base class, can ensure proper initialization.
- -A custom base class can be made for this idiom:
- -- --#include <streambuf> // for std::streambuf -#include <ostream> // for std::ostream - -class fdoutbuf - : public std::streambuf -{ -public: - explicit fdoutbuf( int fd ); - //... -}; - -struct fdostream_pbase -{ - fdoutbuf sbuffer; - - explicit fdostream_pbase( int fd ) - : sbuffer( fd ) - {} -}; - -class fdostream - : private fdostream_pbase - , public std::ostream -{ - typedef fdostream_pbase pbase_type; - typedef std::ostream base_type; - -public: - explicit fdostream( int fd ) - : pbase_type( fd ), base_type( &sbuffer ) - {} - //... -}; -
Other projects can use similar custom base classes. The technique -is basic enough to make a template, with a sample template class in -this library. The main template parameter is the type of the enclosed -member. The template class has several (explicit) constructor member -templates, which implicitly type the constructor arguments and pass them -to the member. The template class uses implicit copy construction and -assignment, cancelling them if the enclosed member is non-copyable.
- -Manually coding a base class may be better if the construction -and/or copying needs are too complex for the supplied template class, -or if the compiler is not advanced enough to use it.
- -Since base classes are unnamed, a class cannot have multiple (direct) -base classes of the same type. The supplied template class has an -extra template parameter, an integer, that exists solely to provide type -differentiation. This parameter has a default value so a single use of a -particular member type does not need to concern itself with the integer.
- -- --#ifndef BOOST_BASE_FROM_MEMBER_MAX_ARITY -#define BOOST_BASE_FROM_MEMBER_MAX_ARITY 10 -#endif - -template < typename MemberType, int UniqueID = 0 > -class boost::base_from_member -{ -protected: - MemberType member; - - base_from_member(); - - template< typename T1 > - explicit base_from_member( T1 x1 ); - - template< typename T1, typename T2 > - base_from_member( T1 x1, T2 x2 ); - - //... - - template< typename T1, typename T2, typename T3, typename T4, - typename T5, typename T6, typename T7, typename T8, typename T9, - typename T10 > - base_from_member( T1 x1, T2 x2, T3 x3, T4 x4, T5 x5, T6 x6, T7 x7, - T8 x8, T9 x9, T10 x10 ); -}; -
The class template has a first template parameter
-MemberType representing the type of the based-member.
-It has a last template parameter UniqueID, that is an
-int
, to differentiate between multiple base classes that use
-the same based-member type. The last template parameter has a default
-value of zero if it is omitted. The class template has a protected
-data member called member that the derived class can use
-for later base classes (or itself).
There is a default constructor and several constructor member -templates. These constructor templates can take as many arguments -(currently up to ten) as possible and pass them to a constructor of -the data member. Since C++ does not allow any way to explicitly state -the template parameters of a templated constructor, make sure that -the arguments are already close as possible to the actual type used in -the data member's desired constructor.
- -The BOOST_BASE_FROM_MEMBER_MAX_ARITY macro constant specifies -the maximum argument length for the constructor templates. The constant -may be overridden if more (or less) argument configurations are needed. The -constant may be read for code that is expandable like the class template and -needs to maintain the same maximum size. (Example code would be a class that -uses this class template as a base class for a member with a flexible set of -constructors.)
- -With the starting example, the fdoutbuf
sub-object needs
-to be encapsulated in a base class that is inheirited before
-std::ostream
.
- --#include <boost/utility/base_from_member.hpp> - -#include <streambuf> // for std::streambuf -#include <ostream> // for std::ostream - -class fdoutbuf - : public std::streambuf -{ -public: - explicit fdoutbuf( int fd ); - //... -}; - -class fdostream - : private boost::base_from_member<fdoutbuf> - , public std::ostream -{ - // Helper typedef's - typedef boost::base_from_member<fdoutbuf> pbase_type; - typedef std::ostream base_type; - -public: - explicit fdostream( int fd ) - : pbase_type( fd ), base_type( &member ) - {} - //... -}; -
The base-from-member idiom is an implementation detail, so it
-should not be visible to the clients (or any derived classes) of
-fdostream
. Due to the initialization order, the
-fdoutbuf
sub-object will get initialized before the
-std::ostream
sub-object does, making the former
-sub-object safe to use in the latter sub-object's construction. Since the
-fdoutbuf
sub-object of the final type is the only sub-object
-with the name "member," that name can be used
-unqualified within the final class.
The base-from-member class templates should commonly involve -only one base-from-member sub-object, usually for attaching a -stream-buffer to an I/O stream. The next example demonstrates how -to use multiple base-from-member sub-objects and the resulting -qualification issues.
- -- --#include <boost/utility/base_from_member.hpp> - -#include <cstddef> // for NULL - -struct an_int -{ - int y; - - an_int( float yf ); -}; - -class switcher -{ -public: - switcher(); - switcher( double, int * ); - //... -}; - -class flow_regulator -{ -public: - flow_regulator( switcher &, switcher & ); - //... -}; - -template < unsigned Size > -class fan -{ -public: - explicit fan( switcher ); - //... -}; - -class system - : private boost::base_from_member<an_int> - , private boost::base_from_member<switcher> - , private boost::base_from_member<switcher, 1> - , private boost::base_from_member<switcher, 2> - , protected flow_regulator - , public fan<6> -{ - // Helper typedef's - typedef boost::base_from_member<an_int> pbase0_type; - typedef boost::base_from_member<switcher> pbase1_type; - typedef boost::base_from_member<switcher, 1> pbase2_type; - typedef boost::base_from_member<switcher, 2> pbase3_type; - - typedef flow_regulator base1_type; - typedef fan<6> base2_type; - -public: - system( double x ); - //... -}; - -system::system( double x ) - : pbase0_type( 0.2 ) - , pbase1_type() - , pbase2_type( -16, &this->pbase0_type::member ) - , pbase3_type( x, static_cast<int *>(NULL) ) - , base1_type( pbase3_type::member, pbase1_type::member ) - , base2_type( pbase2_type::member ) -{ - //... -} -
The final class has multiple sub-objects with the name
-"member," so any use of that name needs qualification by
-a name of the appropriate base type. (Using typedef
s
-ease mentioning the base types.) However, the fix introduces a new
-problem when a pointer is needed. Using the address operator with
-a sub-object qualified with its class's name results in a pointer-to-member
-(here, having a type of an_int boost::base_from_member<an_int,
-0> :: *
) instead of a pointer to the member (having a type of
-an_int *
). The new problem is fixed by qualifying the
-sub-object with "this->
," and is needed just
-for pointers, and not for references or values.
There are some argument conversions in the initialization. The
-constructor argument for pbase0_type
is converted from
-double
to float
. The first constructor
-argument for pbase2_type
is converted from int
-to double
. The second constructor argument for
-pbase3_type
is a special case of necessary conversion; all
-forms of the null-pointer literal in C++ also look like compile-time
-integral expressions, so C++ always interprets such code as an integer
-when it has overloads that can take either an integer or a pointer. The
-last conversion is necessary for the compiler to call a constructor form
-with the exact pointer type used in switcher
's constructor.
Revised: 28 August 2004
- -Copyright 2001, 2003, 2004 Daryle Walker. Use, modification, and distribution -are subject to the Boost Software License, Version 1.0. (See accompanying -file LICENSE_1_0.txt or a copy at <http://www.boost.org/LICENSE_1_0.txt>.)
- - - diff --git a/base_from_member_test.cpp b/base_from_member_test.cpp deleted file mode 100644 index 89328e4..0000000 --- a/base_from_member_test.cpp +++ /dev/null @@ -1,595 +0,0 @@ -// Boost test program for base-from-member class templates -----------------// - -// Copyright 2001, 2003 Daryle Walker. Use, modification, and distribution are -// subject to the Boost Software License, Version 1.0. (See accompanying file -// LICENSE_1_0.txt or a copy atAll 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 |
-
|
- 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& |
-
|
- Defines a type that - represents a reference to type T. Use for functions that - would normally return a T&. | -1 - |
-
const
- T& |
-
|
- Defines a type that - represents a constant reference to type T. Use for - functions that would normally return a const T&. | -1 - |
-
const
- T& |
-
|
- Defines a type that - represents the "best" way to pass a parameter - of type T to a function. | -1,3 - |
-
Notes:
- -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!).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).- -
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 - |
- - - |
- - - |
- - - |
-
- -
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. - |
-
- -
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){} - -};- -
Consider the definition of std::binder1st:
- -template <class Operation> -class binder1st : - public unary_function<typename Operation::second_argument_type, typename Operation::result_type> -{ -protected: - Operation op; - typename Operation::first_argument_type value; -public: - binder1st(const Operation& x, const typename Operation::first_argument_type& y); - typename Operation::result_type operator()(const typename 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:
typename Operation::result_type operator()(typename call_traits<typename 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.
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.
- -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 fill_example.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.
- -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(typename call_traits<T>::value_type t); -}; - -template <class T> -void A<T>::foo(typename call_traits<T>::value_type t) -{ - typename 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.yahoogroups.com/list/boost.
- -.
- -- -
- - - diff --git a/call_traits_test.cpp b/call_traits_test.cpp deleted file mode 100644 index e73ede7..0000000 --- a/call_traits_test.cpp +++ /dev/null @@ -1,405 +0,0 @@ -// boost::compressed_pair test program - -// (C) Copyright John Maddock 2000. -// Use, modification and distribution are subject to the Boost Software License, -// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt). - - -// standalone test program for
![]() |
-
- checked_delete.hpp- |
-
- |
- The header <boost/checked_delete.hpp> defines two - function templates, checked_delete and checked_array_delete, - and two class templates, checked_deleter and checked_array_deleter. -
-The C++ Standard allows, in 5.3.5/5, pointers to incomplete class types to be - deleted with a delete-expression. When the class has a non-trivial - destructor, or a class-specific operator delete, the behavior is undefined. - Some compilers issue a warning when an incomplete type is deleted, but - unfortunately, not all do, and programmers sometimes ignore or disable - warnings.
-A particularly troublesome case is when a smart pointer's destructor, such as - boost::scoped_ptr<T>::~scoped_ptr, is instantiated with an - incomplete type. This can often lead to silent, hard to track failures.
-The supplied function and class templates can be used to prevent these problems, - as they require a complete type, and cause a compilation error otherwise.
--namespace boost -{ - -template<class T> void checked_delete(T * p); -template<class T> void checked_array_delete(T * p); -template<class T> struct checked_deleter; -template<class T> struct checked_array_deleter; - -} --
--- Requires: T must be a complete type. The expression delete p - must be well-formed. -
-- Effects: delete p; -
-
--- Requires: T must be a complete type. The expression delete [] p - must be well-formed. -
-- Effects: delete [] p; -
-
-template<class T> struct checked_deleter -{ - typedef void result_type; - typedef T * argument_type; - void operator()(T * p) const; -}; --
--- Requires: T must be a complete type. The expression delete p - must be well-formed. -
-- Effects: delete p; -
-
-template<class T> struct checked_array_deleter -{ - typedef void result_type; - typedef T * argument_type; - void operator()(T * p) const; -}; --
--- Requires: T must be a complete type. The expression delete [] p - must be well-formed. -
-- Effects: delete [] p; -
-
- The function templates checked_delete and checked_array_delete - were originally part of <boost/utility.hpp>, and the - documentation acknowledged Beman Dawes, Dave Abrahams, Vladimir Prus, Rainer - Deyke, John Maddock, and others as contributors. -
-
-
- Copyright © 2002 by Peter Dimov. Distributed under the Boost Software License, Version
- 1.0. See accompanying file LICENSE_1_0.txt or
- copy at http://www.boost.org/LICENSE_1_0.txt.
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 base-class 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); - - compressed_pair& operator=(const compressed_pair&); - - 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 if either member is a POD type, then that member is not - zero-initialized by the compressed_pair default constructor: it's up to you to - supply an initial value for these types if you want them to have a default - value.
-Note that compressed_pair can not be instantiated if either of the template - arguments is a union type, unless there is compiler support for - boost::is_union, or if boost::is_union is specialised for the union type.
-Finally, a word of caution for Visual C++ 6 users: if either argument is an - empty type, then assigning to that member will produce memory corruption, - unless the empty type has a "do nothing" assignment operator defined. This is - due to a bug in the way VC6 generates implicit assignment operators.
-Revised 08 May 2001
-© 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.yahoogroups.com/list/boost.
-- - diff --git a/compressed_pair_test.cpp b/compressed_pair_test.cpp deleted file mode 100644 index 7687f0a..0000000 --- a/compressed_pair_test.cpp +++ /dev/null @@ -1,395 +0,0 @@ -// boost::compressed_pair test program - -// (C) Copyright John Maddock 2000. -// Use, modification and distribution are subject to the Boost Software License, -// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt). - -// standalone test program for