diff --git a/Assignable.html b/Assignable.html
index d3b3157..942d491 100644
--- a/Assignable.html
+++ b/Assignable.html
@@ -1,109 +1,19 @@
-
-
-
-
-
- Assignable
+ Boost.Utility
+
-
-
- 
-
- 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
-
-
- 
-
- Revised
- 05 December, 2006
-
-
-
- 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)
+
+Automatic redirection failed, please go to
+./doc/html/index.html
+
+
+ Boost.Utility
+
+ 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
index b92ddd6..942d491 100644
--- a/Collection.html
+++ b/Collection.html
@@ -1,534 +1,19 @@
-
-
-
-
-
- Collection
+ Boost.Utility
+
-
-
- 
- Collection
-
- Description
-
- 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:
-
-
- - It is not required to "own" its elements: the lifetime of an element
- in a Collection does not have to match the lifetime of the Collection
- object, though the lifetime of the element should cover the lifetime of
- the Collection object.
-
- - The semantics of copying a Collection object is not defined (it could
- be a deep or shallow copy or not even support copying).
-
- - The associated reference type of a Collection does not have to be a
- real C++ reference.
-
Because of the reduced requirements, some care must be taken when
- writing code that is meant to be generic for all Collection types. In
- particular, a Collection object should be passed by-reference since
- assumptions can not be made about the behaviour of the copy constructor.
-
- Associated types
-
-
-
- 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. |
-
-
-
- Notation
-
-
-
- X |
-
- A type that is a model of Collection. |
-
-
-
- a, b |
-
- Object of type X. |
-
-
-
- T |
-
- The value type of X. |
-
-
-
- Valid expressions
-
- 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 |
-
-
-
- Expression semantics
-
-
-
- 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) |
-
- |
-
-
-
- Complexity guarantees
-
- 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.
-
- Invariants
-
-
-
- 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. |
-
-
-
- Models
-
-
- - array
-
- - array_ptr
-
- - vector<bool>
-
-
- Collection Refinements
-
- 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.
-
- ForwardCollection
-
- 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()). |
-
-
-
- ReversibleCollection
-
- 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()). |
-
-
-
- SequentialCollection
-
- The elements are arranged in a strict linear order. No extra methods are
- required.
-
- RandomAccessCollection
-
- 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(). |
-
-
-
- Notes
-
- [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).
-
- See also
-
- Container
-
-
- 
-
- Revised
- 05
- December, 2006
-
-
-
- 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)
+
+Automatic redirection failed, please go to
+./doc/html/index.html
+
+
+ Boost.Utility
+
+ 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
index 6a7ce65..942d491 100644
--- a/CopyConstructible.html
+++ b/CopyConstructible.html
@@ -1,185 +1,19 @@
-
-
-
-
-
- Copy Constructible
+ Boost.Utility
+
-
-
- 
-
- Copy Constructible
-
- Description
-
- A type is Copy Constructible if it is possible to copy objects of that
- type.
-
- Notation
-
-
-
- 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 |
-
-
-
- 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
-
- Default
- Constructible and Assignable
-
-
- 
-
- Revised
- 05
- December, 2006
-
-
-
- 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)
+
+Automatic redirection failed, please go to
+./doc/html/index.html
+
+
+ Boost.Utility
+
+ 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
index 15b938f..942d491 100644
--- a/LessThanComparable.html
+++ b/LessThanComparable.html
@@ -1,210 +1,19 @@
-
-
-
-
-
-
-
- LessThanComparable
+ Boost.Utility
+
-
-
- 
-
- 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
-
-
-
- 
-
- Revised
- 05
- December, 2006
-
-
-
- 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)
+
+Automatic redirection failed, please go to
+./doc/html/index.html
+
+
+ Boost.Utility
+
+ 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
index e331ca3..942d491 100644
--- a/MultiPassInputIterator.html
+++ b/MultiPassInputIterator.html
@@ -1,95 +1,19 @@
-
-
-
-
-
- MultiPassInputIterator
+ Boost.Utility
+
-
-
- 
-
- Multi-Pass Input Iterator
-
- 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.
-
- Design Notes
-
- 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
-
-
-
- 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)
+
+Automatic redirection failed, please go to
+./doc/html/index.html
+
+
+ Boost.Utility
+
+ 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
index c3c7e44..942d491 100644
--- a/OptionalPointee.html
+++ b/OptionalPointee.html
@@ -1,159 +1,19 @@
-
-
-OptionalPointee Concept
-
-
-
-
-
-Concept: OptionalPointee
-
-Description
-A type is a model of OptionalPointee if it points to (or refers to) a value
-that may not exist. That is, if it has a pointee which might be valid
-(existent) or invalid (inexistent); and it is possible to test whether the
-pointee is valid or not.
-This model does not imply pointer semantics: i.e., it does not imply shallow copy nor
-aliasing.
-Notation
-
-
- T |
- is a type that is a model of OptionalPointee |
-
-
- t |
- is an object of type T or possibly const T |
-
-
-Definitions
-Valid expressions
-
-
- 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 |
- bool(t) |
- bool |
- If the pointee is valid returns true.
- If the pointee is invalid returns false. |
- |
-
-
- Invalidity Test |
- !t |
- bool |
- If the pointee is valid returns false.
- If the pointee is invalid returns true. |
- |
-
-
-
-
-Models
-
-
- - pointers, both builtin and smart.
-
- boost::optional<>
-
-
-
-OptionalPointee and relational operations
-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.
-
-Acknowledgements
-Based on the original concept developed by Augustus Saunders.
-
-
-
-
-
-
-Distributed under the Boost Software License, Version 1.0. See
-www.boost.org/LICENSE_1_0.txt
-
-
-
+
+
+ Boost.Utility
+
+
+
+Automatic redirection failed, please go to
+./doc/html/index.html
+
+
+ Boost.Utility
+
+ 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/call_traits.htm b/call_traits.htm
index b4fe3ee..cda1f2d 100644
--- a/call_traits.htm
+++ b/call_traits.htm
@@ -1,755 +1,19 @@
-
-
-
-
-Call Traits
+ Boost.Utility
+
-
-
-
-
-
-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:
-
-
- - If T is already reference type, then call_traits is
- defined such that references to
- references do not occur (requires partial
- specialization).
- - 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!).
- - 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).
-
-
-
-
-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<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.
-
-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 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.
-
-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(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).
-
+
+Automatic redirection failed, please go to
+./doc/html/utility/utilities/call_traits.html
-
-Revised 01 September 2000
-
-
- Copyright 2000 Steve Cleary, Beman Dawes, Howard
- Hinnant and John Maddock.
- 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
- ).
-
+
+ Boost.Utility
+
+ 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/checked_delete.html b/checked_delete.html
index 1b93256..7a60faf 100644
--- a/checked_delete.html
+++ b/checked_delete.html
@@ -1,15 +1,19 @@
-
-
-Automatic redirection
+ Boost.Utility
+
Automatic redirection failed, please go to
-checked_delete.html.
-© Copyright Beman Dawes, 2001
-Distributed under the Boost Software License, Version 1.0. (See accompanying
-file LICENSE_1_0.txt or copy
-at www.boost.org/LICENSE_1_0.txt)
+../core/doc/html/core/checked_delete.html
+
+
+ Boost.Utility
+
+ 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/compressed_pair.htm b/compressed_pair.htm
index 0b99bf7..9937a44 100644
--- a/compressed_pair.htm
+++ b/compressed_pair.htm
@@ -1,16 +1,19 @@
-
-
-
-
+ Boost.Utility
+
Automatic redirection failed, please go to
-doc/html/compressed_pair.html
+./doc/html/utility/utilities/compressed_pair.html
+
+
+ Boost.Utility
+
+ 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/doc/BOOST_BINARY.qbk b/doc/BOOST_BINARY.qbk
new file mode 100644
index 0000000..4b207ce
--- /dev/null
+++ b/doc/BOOST_BINARY.qbk
@@ -0,0 +1,74 @@
+[/
+ / Copyright (c) 2012 Marshall Clow
+ / Copyright (c) 2021, Alan Freitas
+ / 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)
+ /]
+
+[/===============]
+[#sec:BOOST_BINARY]
+[section Binary Integer Literals]
+[/===============]
+
+[heading Introduction]
+
+The macro `BOOST_BINARY` is used for the representation of binary
+literals. It takes as an argument a binary number arranged as an
+arbitrary amount of 1s and 0s in groupings of length 1 to 8, with
+groups separated by spaces. The macro serves as a replacement for
+[@https://en.cppreference.com/w/cpp/language/integer_literal binary integer literals],
+adopted in C++14.
+
+The type of the literal yielded is determined by the same rules as
+those of [@https://en.cppreference.com/w/cpp/language/integer_literal hex and octal literals].
+By implementation, this macro expands directly to an octal literal during preprocessing, so
+there is no overhead at runtime and the result is usable in any place that an octal literal
+would be.
+
+In order to directly support binary literals with suffixes,
+additional macros of the form `BOOST_BINARY_XXX` are also
+provided, where `XXX` is a standard integer suffix in all capital
+letters.
+
+In addition, LL and ULL suffixes may be used for representing
+`long long` and `unsigned long long` types in compilers which provide
+them as an extension.
+
+The `BOOST_BINARY` family of macros resides in the header
+[@../../../include/boost/utility/binary.hpp ].
+
+[heading Example]
+
+```
+void foo( int );
+
+void foo( unsigned long );
+
+void bar()
+{
+ int value1 = BOOST_BINARY( 100 111000 01 1 110 );
+
+ unsigned long value2 = BOOST_BINARY_UL( 100 001 ); // unsigned long
+
+ long long value3 = BOOST_BINARY_LL( 11 000 ); // long long if supported
+
+ __assert__( BOOST_BINARY( 10010 )
+ & BOOST_BINARY( 11000 )
+ == BOOST_BINARY( 10000 )
+ );
+
+ foo( BOOST_BINARY( 1010 ) ); // calls the first foo
+
+ foo( BOOST_BINARY_LU( 1010 ) ); // calls the second foo
+}
+```
+
+[heading Acknowledgments]
+
+Contributed by Matt Calabrese.
+
+[endsect]
+
+
+
+
diff --git a/doc/base_from_member.qbk b/doc/base_from_member.qbk
index 9801214..d17559d 100644
--- a/doc/base_from_member.qbk
+++ b/doc/base_from_member.qbk
@@ -1,5 +1,6 @@
[/
Copyright 2001, 2003, 2004, 2012 Daryle Walker.
+ Copyright (c) 2021, Alan Freitas
Distributed under the Boost Software License, Version 1.0.
@@ -7,48 +8,43 @@
or copy at http://boost.org/LICENSE_1_0.txt
]
-[article Base_From_Member
- [quickbook 1.5]
- [authors [Walker, Daryle]]
- [copyright 2001, 2003, 2004, 2012 Daryle Walker]
- [license
- 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])
- ]
-]
+[section:base_from_member Base from Member]
+[block'''''']
-[section Rationale]
+[heading Introduction]
+The class templates __base_from_member__ support the base-from-member idiom.
When developing a class, sometimes a base class needs to be initialized
with a member of the current class. As a na\u00EFve example:
- #include /* for std::streambuf */
- #include /* for std::ostream */
+```
+#include /* for std::streambuf */
+#include /* for std::ostream */
- class fdoutbuf
- : public std::streambuf
- {
- public:
- explicit fdoutbuf( int fd );
- //...
- };
+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 ) {}
- //...
- };
+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. [@http://www.moocat.org 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
+order in his favor. Base classes are initialized 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.
@@ -58,7 +54,7 @@ A custom base class can be made for this idiom:
#include /* for std::ostream */
class fdoutbuf
- : public std::streambuf
+ : public __std_streambuf__
{
public:
explicit fdoutbuf( int fd );
@@ -75,10 +71,10 @@ A custom base class can be made for this idiom:
class fdostream
: private fdostream_pbase
- , public std::ostream
+ , public __std_ostream__
{
typedef fdostream_pbase pbase_type;
- typedef std::ostream base_type;
+ typedef __std_ostream__ base_type;
public:
explicit fdostream( int fd )
@@ -104,9 +100,8 @@ 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.
-[endsect]
-[section Synopsis]
+[heading Synopsis]
#include /* exposition only */
@@ -115,41 +110,41 @@ type does not need to concern itself with the integer.
#endif
template < typename MemberType, int UniqueID = 0 >
- class boost::base_from_member
+ class __boost_base_from_member__
{
protected:
MemberType member;
#if ``['C++11 is in use]``
template< typename ...T >
- explicit constexpr base_from_member( T&& ...x )
- noexcept( std::is_nothrow_constructible::value );
+ explicit constexpr __base_from_member__( T&& ...x )
+ noexcept( __std_is_nothrow_constructible__::value );
#else
- base_from_member();
+ __base_from_member__();
template< typename T1 >
- explicit base_from_member( T1 x1 );
+ explicit __base_from_member__( T1 x1 );
template< typename T1, typename T2 >
- base_from_member( T1 x1, T2 x2 );
+ __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,
+ __base_from_member__( T1 x1, T2 x2, T3 x3, T4 x4, T5 x5, T6 x6, T7 x7,
T8 x8, T9 x9, T10 x10 );
#endif
};
template < typename MemberType, int UniqueID >
- class base_from_member
+ class __base_from_member__
{
protected:
MemberType& member;
- explicit constexpr base_from_member( MemberType& x )
+ explicit constexpr __base_from_member__( MemberType& x )
noexcept;
};
@@ -158,21 +153,21 @@ 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).
+called `member` that the derived class can use for later base classes or
+itself.
If the appropriate features of C++11 are present, there will be a single
constructor template. It implements ['perfect forwarding] to the best
-constructor call of `member` (if any). The constructor template is marked
+constructor call of `member` if any. The constructor template is marked
both `constexpr` and `explicit`. The former will be ignored if the
-corresponding inner constructor call (of `member`) does not have the marker.
+corresponding inner constructor call of `member` does not have the marker.
The latter binds the other way; always taking effect, even when the inner
constructor call does not have the marker. The constructor template
-propagates the `noexcept` status of the inner constructor call. (The
+propagates the `noexcept` status of the inner constructor call. The
constructor template has a trailing parameter with a default value that
disables the template when its signature is too close to the signatures of
the automatically-defined non-template copy- and/or move-constructors of
-`base_from_member`.)
+__base_from_member__.
On earlier-standard compilers, there is a default constructor and several
constructor member templates. These constructor templates can take as many
@@ -195,150 +190,157 @@ 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.) This constant is ignored when C++11 features are present.
-[endsect]
-[section Usage]
+[heading Basic Usage]
With the starting example, the `fdoutbuf` sub-object needs to be
-encapsulated in a base class that is inheirited before `std::ostream`.
+encapsulated in a base class that is inherited before `__std_ostream__`.
- #include
+```
+#include
- #include // for std::streambuf
- #include // for std::ostream
+#include // for std::streambuf
+#include // for __std_ostream__
- class fdoutbuf
- : public std::streambuf
- {
- public:
- explicit fdoutbuf( int fd );
- //...
- };
+class fdoutbuf
+ : public __std_streambuf__
+{
+public:
+ explicit fdoutbuf( int fd );
+ //...
+};
- class fdostream
- : private boost::base_from_member
- , public std::ostream
- {
- // Helper typedef's
- typedef boost::base_from_member pbase_type;
- typedef std::ostream base_type;
+class fdostream
+ : private __boost_base_from_member__
+ , public __std_ostream__
+{
+ // Helper typedef's
+ typedef __boost_base_from_member__ pbase_type;
+ typedef __std_ostream__ base_type;
- public:
- explicit fdostream( int fd )
- : pbase_type( fd ), base_type( &member ){}
- //...
- };
+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
+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.
-[endsect]
-[section Example]
+[heading Multiple Sub-Objects]
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
+```
+#include
- #include /* for NULL */
+#include /* for NULL */
- struct an_int
- {
- int y;
+struct an_int
+{
+ int y;
- an_int( float yf );
- };
+ an_int( float yf );
+};
- class switcher
- {
- public:
- switcher();
- switcher( double, int * );
- //...
- };
+class switcher
+{
+public:
+ switcher();
+ switcher( double, int * );
+ //...
+};
- class flow_regulator
- {
- public:
- flow_regulator( switcher &, switcher & );
- //...
- };
+class flow_regulator
+{
+public:
+ flow_regulator( switcher &, switcher & );
+ //...
+};
- template < unsigned Size >
- class fan
- {
- public:
- explicit fan( switcher );
- //...
- };
+template < unsigned Size >
+class fan
+{
+public:
+ explicit fan( switcher );
+ //...
+};
- class system
- : private boost::base_from_member
- , private boost::base_from_member
- , private boost::base_from_member
- , private boost::base_from_member
- , protected flow_regulator
- , public fan<6>
- {
- // Helper typedef's
- typedef boost::base_from_member pbase0_type;
- typedef boost::base_from_member pbase1_type;
- typedef boost::base_from_member pbase2_type;
- typedef boost::base_from_member pbase3_type;
+class system
+ : private __boost_base_from_member__
+ , private __boost_base_from_member__
+ , private __boost_base_from_member__
+ , private __boost_base_from_member__
+ , protected flow_regulator
+ , public fan<6>
+{
+ // Helper typedef's
+ typedef __boost_base_from_member__ pbase0_type;
+ typedef __boost_base_from_member__ pbase1_type;
+ typedef __boost_base_from_member__ pbase2_type;
+ typedef __boost_base_from_member__ pbase3_type;
- typedef flow_regulator base1_type;
- typedef fan<6> base2_type;
+ typedef flow_regulator base1_type;
+ typedef fan<6> base2_type;
- public:
- system( double x );
- //...
- };
+public:
+ system( double x );
+ //...
+};
- system::system( double x )
- : pbase0_type( 0.2 )
- , pbase1_type()
- , pbase2_type( -16, &this->pbase0_type::member.y )
- , pbase3_type( x, static_cast(NULL) )
- , base1_type( pbase3_type::member, pbase1_type::member )
- , base2_type( pbase2_type::member )
- {
- //...
- }
+system::system( double x )
+ : pbase0_type( 0.2 )
+ , pbase1_type()
+ , pbase2_type( -16, &this->pbase0_type::member.y )
+ , pbase3_type( x, static_cast(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.
+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__:: *`)
+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++ (except
`nullptr` from C++11) 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. (If C++11's `nullptr` is used, it still needs a
-conversion if multiple pointer types can be accepted in a constructor call
-but `std::nullptr_t` cannot.)
+take either an integer or a pointer.
-[endsect]
+The last conversion is necessary for the compiler to call a constructor form
+ with the exact pointer type used in `switcher`'s constructor. (If C++11's
+ __nullptr__ is used, it still needs a conversion if multiple pointer types can
+ be accepted in a constructor call but `__std_nullptr_t__` cannot.)
-[section Acknowledgments]
+[heading Acknowledgments]
+
+Author: Walker, Daryle
+
+Copyright 2001, 2003, 2004, 2012 Daryle Walker
* [@http://www.boost.org/people/ed_brey.htm Ed Brey] suggested some interface
changes.
@@ -353,10 +355,10 @@ the idiom of how to use a class member for initializing a base class.
* Jonathan Turkanis supplied an implementation of generating the constructor
templates that can be controlled and automated with macros. The
-implementation uses the [@../../../preprocessor/index.html Preprocessor library].
+implementation uses the [@boost:/doc/html/preprocessor/index.html Preprocessor library].
* [@http://www.boost.org/people/daryle_walker.html">Daryle Walker] started the
-library. Contributed the test file [@../../test/base_from_member_test.cpp
+library. Contributed the test file [@../../../test/base_from_member_test.cpp
base_from_member_test.cpp].
[endsect]
diff --git a/doc/call_traits.qbk b/doc/call_traits.qbk
new file mode 100644
index 0000000..60aa36a
--- /dev/null
+++ b/doc/call_traits.qbk
@@ -0,0 +1,432 @@
+[/
+ / Copyright (c) 2012 Marshall Clow
+ / Copyright (c) 2021, Alan Freitas
+ /
+ / 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)
+ /]
+
+[/===============]
+[section Call Traits]
+[/===============]
+
+[heading Introduction]
+
+All of the contents of [@../../../include/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 `typedef`s defined
+as in the table below. The purpose of __call_traits__ is to ensure
+that problems like [link sec:refs "references to references"]
+never occur, and that parameters are passed in the most efficient
+manner possible, as in the [link sec:examples 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__ cannot be used with array types, although it can still be
+used to solve the reference to reference problem.
+
+[table __call_traits__ types
+ [[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:
+
+# If `T` is already reference type, then __call_traits__ is
+ defined such that [link sec:refs "references to references"]
+ do not occur (requires partial specialization).
+# 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!).
+# 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).
+
+
+[heading Copy constructibility]
+
+The following table defines which __call_traits__ types can always
+be copy-constructed from which other types:
+
+[table Which __call_traits__ types can always be copy-constructed from which other types
+ [[] [To `T`] [To `value_type`] [To `reference`] [To `const_reference`] [To `param_type`]]
+ [[From `T`] [iff `T` is copy constructible] [iff `T` is copy constructible] [Yes] [Yes] [Yes]]
+ [[From `value_type`] [iff `T` is copy constructible] [iff `T` is copy constructible] [No] [No] [Yes]]
+ [[From `reference`] [iff `T` is copy constructible] [iff `T` is copy constructible] [Yes] [Yes] [Yes]]
+ [[From `const_reference`] [iff `T` is copy constructible] [No] [No] [Yes] [Yes]]
+ [[From `param_type`] [iff `T` is copy constructible] [iff `T` is copy constructible] [No] [No] [Yes]]
+]
+
+If `T` is an assignable type the following assignments are possible:
+
+[table Which __call_traits__ types are assignable from which other types
+ [[] [To `T`] [To `value_type`] [To `reference`] [To `const_reference`] [To `param_type`]]
+ [[From `T`] [Yes] [Yes] [-] [-] [-]]
+ [[From `value_type`] [Yes] [Yes] [-] [-] [-]]
+ [[From `reference`] [Yes] [Yes] [-] [-] [-]]
+ [[From `const_reference`] [Yes] [Yes] [-] [-] [-]]
+ [[From `param_type`] [Yes] [Yes] [-] [-] [-]]
+]
+
+[#sec:examples]
+[heading Examples]
+
+The following table shows the effect that __call_traits__ has on
+various types.
+
+[table Examples of __call_traits__ types
+ [[] [__call_traits__::`value_type`] [__call_traits__::`reference`] [__call_traits__::`const_reference`] [__call_traits__::`param_type`] [Applies to:]]
+ [[From `my_class`] [`my_class`] [`my_class&`] [`const my_class&`] [`my_class const&`] [All user-defined types]]
+ [[From `int`] [`int`] [`int&`] [`const int&`] [`int const`] [All small built-in types]]
+ [[From `int*`] [`int*`] [`int*&`] [`int* const &`] [`int* const`] [All pointer types]]
+ [[From `int&`] [`int&`] [`int&`] [`const int&`] [`int&`] [All reference types]]
+ [[From `const int&`] [`const int&`] [`const int&`] [`const int&`] [`const int&`] [All constant reference types]]
+ [[From `int[3]`] [`const int*`] [`int(&)[3]`] [`const int(&)[3]`] [`const int* const`] [All array types]]
+ [[From `const int[3]`] [`const int*`] [`const int(&)[3]`] [`const int(&)[3]`] [`const int *const`] [All constant array types]]
+]
+
+The table assumes the compiler supports partial
+specialization: if it does not then all types behave in
+the same way as the entry for "`my_class`", and
+__call_traits__ can not be used with reference or array types.
+
+[heading Example 1:]
+
+The following class is a trivial class that stores some type `T`
+by value (see the [@../../../test/call_traits_test.cpp `call_traits_test.cpp`]
+file). The aim is to illustrate how each of the available
+__call_traits__ `typedef`s may be used:
+
+```
+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() { return v_; }
+ // return by_ref:
+ reference get() { return v_; }
+ const_reference const_get()const { return v_; }
+ // pass value:
+ void call(param_type p){}
+
+};
+```
+
+[#sec:refs]
+[heading Example 2 (the reference to reference problem):]
+
+Consider the definition of __std_binder1st__:
+
+```
+template
+class binder1st :
+ public __std_unary_function__
+{
+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__::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.
+
+[#sec:example3]
+[heading 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 __std_make_pair__ to pointers, but __call_traits__ provides a
+better automatic solution that works safely even in generic code where the
+cast might do the wrong thing:
+
+```
+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);
+}
+```
+
+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
+__std_make_pair__ are not expressed in terms of __call_traits__: doing so
+would prevent template argument deduction from functioning.
+
+[#sec:example4]
+[heading 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 [@boost:/doc/html/type_traits/examples/fill_example.cpp `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++ implementation is
+used, but with the passed parameter "optimized" using
+__call_traits__:
+
+```
+template
+struct filler
+{
+ template
+ static void do_fill(I first, I last, typename __boost_call_traits__::param_type val)
+ {
+ while(first != last)
+ {
+ *first = val;
+ ++first;
+ }
+ }
+};
+
+template <>
+struct filler
+{
+ template
+ static void do_fill(I first, I last, T val)
+ {
+ __std_memset__(first, val, last-first);
+ }
+};
+
+template
+inline void fill(I first, I last, const T& val)
+{
+ enum { can_opt = boost::is_pointer::value
+ && boost::is_arithmetic::value
+ && (sizeof(T) == 1) };
+ typedef filler filler_t;
+ filler_t::template do_fill(first, last, val);
+}
+```
+
+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__.
+
+[heading Rationale]
+
+The following notes are intended to briefly describe the
+rationale 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 [@https://en.cppreference.com/w/cpp/language/types fundamental
+types], 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 [link sec:example4 Example 4]). In any case this should never
+be any worse than existing practice.
+
+Pointers follow the same rationale as small built-in types.
+
+For reference types the rationale follows [link sec:refs 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
+struct A
+{
+ void foo(T t);
+};
+```
+
+In this case if we instantiate `A` then the declared type of
+the parameter passed to member function `foo` is `int[2]`, but its
+actual type is `const int*`. If we try to use the type `T` within the
+function body, then there is a strong likelihood that our code will not compile:
+
+```
+template
+void A::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
+struct A
+{
+ void foo(typename __call_traits__::value_type t);
+};
+
+template
+void A::foo(typename __call_traits__::value_type t)
+{
+ typename __call_traits__::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 -
+[link sec:example3 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 does not 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.
+
+[endsect]
+
+
+
+
diff --git a/doc/compressed_pair.qbk b/doc/compressed_pair.qbk
index eac4266..bdc8768 100644
--- a/doc/compressed_pair.qbk
+++ b/doc/compressed_pair.qbk
@@ -1,5 +1,6 @@
[/
Copyright 2000 Beman Dawes & John Maddock.
+ Copyright (c) 2021, Alan Freitas
Distributed under the Boost Software License, Version 1.0.
@@ -7,89 +8,77 @@
or copy at http://boost.org/LICENSE_1_0.txt
]
-[article Compressed_Pair
- [quickbook 1.5]
- [authors [Cleary, Steve]]
- [authors [Dawes, Beman]]
- [authors [Hinnant, Howard]]
- [authors [Maddock, John]]
- [copyright 2000 Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock]
- [license
- 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])
- ]
-]
+[section Compressed Pair]
-[section Overview]
+[heading Introduction]
-All of the contents of `` are defined inside
+All of the contents of [@../../../include/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.
+The class __compressed_pair__ is very similar to __std_pair__. However, if either of
+the template arguments are empty classes, then the
+[@https://en.cppreference.com/w/cpp/language/ebo ['empty base-class optimisation]]
+is applied to compress the size of the pair.
-[endsect]
+[heading Synopsis]
-[section Synopsis]
+```cpp
+template
+class __compressed_pair__
+{
+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;
- template
- class compressed_pair
- {
- 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);
+ explicit compressed_pair(first_param_type x);
+ explicit compressed_pair(second_param_type y);
- 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&);
- compressed_pair& operator=(const compressed_pair&);
+ first_reference first();
+ first_const_reference first() const;
- first_reference first();
- first_const_reference first() const;
+ second_reference second();
+ second_const_reference second() const;
- second_reference second();
- second_const_reference second() const;
-
- void swap(compressed_pair& y);
- };
+ 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
+__compressed_pair__ can be instantiated for reference and array types,
+however in these cases the range of constructors that can be used is
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
+Note that if either member is a [@https://en.cppreference.com/w/cpp/named_req/PODType POD]
+type, then that member is not zero-initialized by the __compressed_pair__ default constructor:
+it is 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
+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.
+[@boost:/doc/html/type_traits/index.html `boost::is_union`], or
+if [@boost:/doc/html/type_traits/index.html `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.
-[endsect]
-
-[section Acknowledgments]
+[heading Acknowledgments]
Based on contributions by Steve Cleary, Beman Dawes, Howard Hinnant and
John Maddock.
diff --git a/doc/declval.qbk b/doc/declval.qbk
deleted file mode 100644
index 22ba11e..0000000
--- a/doc/declval.qbk
+++ /dev/null
@@ -1,114 +0,0 @@
-[/
- / Copyright (c) 2008 Howard Hinnant
- / Copyright (c) 2009-2012 Vicente J. Botet Escriba
- /
- / 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)
- /]
-
-[article Declval
- [quickbook 1.5]
- [authors [Hinnant, Howard]]
- [authors [Botet Escriba, Vicente J.]]
- [copyright 2008 Howard Hinnant]
- [copyright 2009-2012 Vicente J. Botet Escriba]
- [license
- 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])
- ]
-]
-
-[/===============]
-[section Overview]
-[/===============]
-
-The motivation for `declval` was introduced in [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2958.html#Value N2958:
-Moving Swap Forward]. Here follows a rewording of this chapter.
-
-With the provision of decltype, late-specified return types, and default template-arguments for function templates a
-new generation of SFINAE patterns will emerge to at least partially compensate the lack of concepts on the C++0x timescale.
-Using this technique, it is sometimes necessary to obtain an object of a known type in a non-using context, e.g. given the declaration
-
- template
- T&& declval(); // not used
-
-as part of the function template declaration
-
- template
- decltype(static_cast(declval())) convert(From&&);
-
-or as part of a class template definition
-
- template class result_of;
-
- template
- struct result_of
- {
- typedef decltype(declval()(declval()...)) type;
- };
-
-The role of the function template declval() is a transformation of a type T into a value without using or evaluating this function.
-The name is supposed to direct the reader's attention to the fact that the expression `declval()` is an lvalue if and only if
-T is an lvalue-reference, otherwise an rvalue. To extend the domain of this function we can do a bit better by changing its declaration to
-
- template
- typename std::add_rvalue_reference::type declval(); // not used
-
-which ensures that we can also use cv void as template parameter. The careful reader might have noticed that `declval()`
-already exists under the name create() as part of the definition of the semantics of the type trait is_convertible in the C++0x standard.
-
-The provision of a new library component that allows the production of values in unevaluated expressions is considered
-important to realize constrained templates in C++0x where concepts are not available.
-This extremely light-weight function is expected to be part of the daily tool-box of the C++0x programmer.
-
-[endsect]
-
-
-[/=================]
-[section:reference Reference ]
-[/=================]
-
-`#include `
-
- namespace boost {
-
- template
- typename add_rvalue_reference::type declval() noexcept; // as unevaluated operand
-
- } // namespace boost
-
-
-The library provides the function template declval to simplify the definition of expressions which occur as unevaluated operands.
-
- template
- typename add_rvalue_reference::type declval();
-
-[*Remarks:] If this function is used, the program is ill-formed.
-
-[*Remarks:] The template parameter T of declval may be an incomplete type.
-
-[*Example:]
-
- template
- decltype(static_cast(declval())) convert(From&&);
-
-Declares a function template convert which only participates in overloading if the type From can be explicitly converted to type To.
-
-[endsect]
-
-[/===============]
-[section History]
-[/===============]
-
-[heading boost 1.50]
-
-Fixes:
-
-* [@http://svn.boost.org/trac/boost/ticket/6570 #6570] Adding noexcept to boost::declval.
-
-[endsect]
-
-
-
-
diff --git a/doc/in_place_factory.qbk b/doc/in_place_factory.qbk
new file mode 100644
index 0000000..f36cdab
--- /dev/null
+++ b/doc/in_place_factory.qbk
@@ -0,0 +1,300 @@
+[/
+ / Copyright (c) 2012 Marshall Clow
+ / Copyright (c) 2021, Alan Freitas
+ /
+ / 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)
+ /]
+
+[/===============]
+[#sec:in_place_factory]
+[section In-place Factory]
+[/===============]
+
+[heading Introduction]
+
+Suppose we have a class
+
+```
+struct X
+{
+ X ( int, _std__string_ ) ;
+};
+```
+
+And a container for it which supports an empty state. That is, a container which can contain zero objects:
+
+```
+struct C
+{
+ C() : contained_(0) {}
+ ~C() { delete contained_ ; }
+ X* contained_ ;
+};
+```
+
+A container designed to support an empty state typically does not require the contained type to be
+__DefaultConstructible__, but it typically requires it to be __CopyConstructible__ as a mechanism to
+initialize the object to store:
+
+```
+struct C
+{
+ C() : contained_(0) {}
+ C ( X const& v ) : contained_ ( new X(v) ) {}
+ ~C() { delete contained_ ; }
+ X* contained_ ;
+};
+```
+
+There is a subtle problem with this: since the mechanism used to initialize the stored object is copy construction,
+there must exist a previously constructed source object to copy from. This object is likely to be temporary and serve
+no purpose besides being the source:
+
+```
+void foo()
+{
+ // Temporary object created.
+ C c( X(123,"hello") ) ;
+}
+```
+
+A solution to this problem is to support direct construction of the contained
+object right in the container's storage.
+
+In this scheme, the user supplies the arguments for the `X` constructor
+directly to the container:
+
+```
+struct C
+{
+ C() : contained_(0) {}
+ C ( X const& v ) : contained_ ( new X(v) ) {}
+ C ( int a0, std::string a1 ) : contained_ ( new X(a0,a1) ) {}
+ ~C() { delete contained_ ; }
+ X* contained_ ;
+};
+```
+
+```
+void foo()
+{
+ // Wrapped object constructed in-place
+ // No temporary created.
+ C c(123,"hello");
+}
+```
+
+Clearly, this solution does not scale well since the container must duplicate all the constructor overloads
+from the contained type, or at least all those which are to be supported directly in the container.
+
+[heading Framework]
+
+This library proposes a framework to allow some containers to directly construct contained objects in-place without requiring
+the entire set of constructor overloads from the contained type. It also allows the container to remove the __CopyConstructible__
+requirement from the contained type since objects can be directly constructed in-place without need of a copy.
+
+The only requirement on the container is that it must provide proper storage. That is, the container should be
+correctly aligned and sized. Naturally, the container will typically support uninitialized storage to avoid the
+in-place construction to override a fully-constructed object, as this would defeat the purpose of in-place construction.
+
+For this purpose, the framework provides two concepts called: InPlaceFactories and TypedInPlaceFactories.
+Helpers to declare these classes are declared in [@../../../include/boost/utility/in_place_factory.hpp ``]
+and [@../../../include/boost/utility/typed_in_place_factory.hpp ``].
+
+Essentially, these classes hold a sequence of actual parameters and a method to construct an object in place using these parameters.
+Each member of the family differs only in the number and type of the parameter list. The first family
+takes the type of the object to construct directly in method provided for that
+purpose, whereas the second family incorporates that type in the factory class
+itself. From the container point of view, using the framework amounts to calling the
+factory's method to contruct the object in place. From the user point of view, it amounts to creating
+the right factory object to hold the parameters and pass it to the container.
+
+The following simplified example shows the basic idea. A complete example follows the formal specification of the framework:
+
+```
+struct C
+{
+ template
+ C ( InPlaceFactory const& aFactory )
+ :
+ contained_ ( uninitialized_storage() )
+ {
+ aFactory.template apply(contained_);
+ }
+
+ ~C()
+ {
+ contained_ -> X::~X();
+ delete[] contained_ ;
+ }
+
+ char* uninitialized_storage() { return new char[sizeof(X)] ; }
+
+ char* contained_ ;
+};
+
+void foo()
+{
+ C c( in_place(123,"hello") ) ;
+}
+
+```
+
+[heading Specification]
+
+The following is the first member of the family of `InPlaceFactory` classes, along with its corresponding helper template function.
+The rest of the family varies only in the number and type of template and constructor parameters.
+
+
+```
+namespace boost {
+
+struct __in_place_factory_base__ {};
+
+template
+class in_place_factory : public __in_place_factory_base__
+{
+ public:
+ in_place_factory ( A0 const& a0 ) : m_a0(a0) {}
+
+ template< class T >
+ void apply ( void* address ) const
+ {
+ new (address) T(m_a0);
+ }
+
+ private:
+ A0 const& m_a0 ;
+};
+
+template
+in_place_factory in_place ( A0 const& a0 )
+{
+ return in_place_factory(a0);
+}
+
+}
+```
+
+Similarly, the following is the first member of the family of `typed_in_place_factory` classes, along with its corresponding
+helper template function. The rest of the family varies only in the number and type of template and constructor parameters.
+
+```
+namespace boost {
+
+struct __typed_in_place_factory_base__ {};
+
+template
+class typed_in_place_factory : public __typed_in_place_factory_base__
+{
+ public:
+ typed_in_place_factory ( A0 const& a0 ) : m_a0(a0) {}
+
+ void apply ( void* address ) const
+ {
+ new (address) T(m_a0);
+ }
+
+ private:
+ A0 const& m_a0 ;
+};
+
+template
+typed_in_place_factory in_place ( A0 const& a0 )
+{
+ return typed_in_place_factory(a0);
+}
+}
+```
+
+As you can see, the `in_place_factory` and `typed_in_place_factory` template classes vary only in the way they specify
+the target type: in the first family, the type is given as a template argument to the apply member function while in the
+second it is given directly as part of the factory class.
+
+When the container holds a unique non-polymorphic type, such as the case of [@boost:/doc/html/optional/index.html Boost.Optional],
+it knows the exact dynamic-type of the contained object and can pass it to the `apply()` method of a non-typed factory.
+In this case, end users can use an `in_place_factory` instance which can be constructed without the type of the object to construct.
+
+However, if the container holds heterogeneous or polymorphic objects, such as the case of [@boost:/doc/html/variant/index.html Boost.Variant],
+the dynamic-type of the object to be constructed must be known by the factory. In this case, end users must use a `typed_in_place_factory`
+instead.
+
+[heading Container-side Usage]
+
+As shown in the introductory simplified example, the container class must contain methods that accept an instance of
+these factories and pass the object's storage to the factory's apply method.
+
+However, the type of the factory class cannot be completely specified in the container class because that would
+defeat the whole purpose of the factories which is to allow the container to accept a variadic argument list
+for the constructor of its contained object.
+
+The correct function overload must be based on the only distinctive and common
+characteristic of all the classes in each family: the base class.
+
+Depending on the container class, you can use `enable_if` to generate the right overload, or use the following
+dispatch technique, which is used in the [@boost:/doc/html/optional/index.html Boost.Optional] class:
+
+
+```
+struct C
+{
+ C() : contained_(0) {}
+ C ( X const& v ) : contained_ ( new X(v) ) {}
+
+ template
+ C ( Expr const& expr )
+ :
+ contained_ ( uninitialized_storage() )
+ {
+ construct(expr,&expr);
+ }
+
+ ~C() { delete contained_ ; }
+
+ template
+ void construct ( InPlaceFactory const& aFactory, boost::__in_place_factory_base__* )
+ {
+ aFactory.template apply(contained_);
+ }
+
+ template
+ void construct ( TypedInPlaceFactory const& aFactory, boost::__typed_in_place_factory_base__* )
+ {
+ aFactory.apply(contained_);
+ }
+
+ X* uninitialized_storage() { return static_cast(new char[sizeof(X)]) ; }
+
+ X* contained_ ;
+};
+```
+
+[heading User-side Usage]
+
+End users pass to the container an instance of a factory object holding the actual parameters needed to construct the
+contained object directly within the container. For this, the helper template function `in_place` is used.
+
+The call `in_place(a0,a1,a2,...,an)` constructs a (non-typed) `in_place_factory` instance with the given argument list.
+
+The call `in_place(a0,a1,a2,...,an)` constructs a `typed_in_place_factory` instance with the given argument list for the
+type `T`.
+
+```
+void foo()
+{
+ C a( in_place(123, "hello") ) ; // in_place_factory passed
+ C b( in_place(456, "world") ) ; // typed_in_place_factory passed
+}
+
+```
+
+[heading Acknowledgments]
+
+Copyright Fernando Luis Cacciola Carballal, 2004
+
+[endsect]
+
+
+
+
diff --git a/doc/operators.qbk b/doc/operators.qbk
new file mode 100644
index 0000000..9fcc4a7
--- /dev/null
+++ b/doc/operators.qbk
@@ -0,0 +1,1986 @@
+[/
+ / Copyright (c) 2012 Marshall Clow
+ / Copyright (c) 2021, Alan Freitas
+ /
+ / 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)
+ /]
+
+[/===============]
+[#sec:operators]
+[section Operators]
+[/===============]
+
+[heading Introduction]
+
+The header [@../../../include/boost/operators.hpp ``] supplies
+several sets of class templates in `namespace boost`. These templates define
+operators at namespace scope in terms of a minimal number of fundamental
+operators provided by the class.
+
+[#sec:rationale]
+[heading 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`
+is equivalent to `!(x < y)`).
+
+Replicating this boilerplate for multiple classes is both tedious and
+error-prone. The [@../../../include/boost/operators.hpp ``] templates
+help by generating operators for you at namespace scope based on other
+operators you have defined in your class.
+
+If, for example, you declare a class like this:
+
+```
+class MyInt
+: boost::__operators__
+{
+ 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>`, `operator<=`, `operator>=`, and the binary `operator+`.
+
+[link sec:two_arg Two-argument forms] of the templates are also provided to allow interaction with other types.
+
+[#sec:semantics]
+This is a ['Summary of Template Semantics]:
+
+# Each operator template completes the concept(s) it describes by defining overloaded operators for its target class.
+# The name of an operator class template indicates the [link sec:concepts_note concept] that its target class will model.
+# Usually, the target class uses an instantiation of the operator class template as a base class. Some operator templates support an
+ [link sec:explicit_instantiation alternate method].
+# The concept can be compound, i.e. it may represent a common combination of other, simpler concepts.
+# Most operator templates require their target class to support operations related to the operators supplied by
+ the template. In accordance with widely accepted [@http://www.gotw.ca/gotw/004.htm coding style recommendations], the
+ target class is often required to supply the assignment counterpart operator of the concept's "main operator."
+ For example, the `addable` template requires `operator+=(T const&)` and in turn supplies `operator+(T const&, T const&)`.
+
+[#sec:concepts_note]
+
+['Note on the use of concepts]: The discussed concepts are not necessarily the standard library's
+concepts, such as __CopyConstructible__, although some of them could
+be; they are what we call ['concepts with a small 'c']. In
+particular, they are different from the former ones in that they ['do
+not] describe precise semantics of the operators they require to be
+defined, except the requirements that (a) the semantics of the operators
+grouped in one concept should be consistent (e.g. effects of
+evaluating of `a += b` and `a = a + b` expressions should be the
+same), and (b) that the return types of the operators should follow
+semantics of return types of corresponding operators for built-in types
+(e.g. `operator<` should return a type convertible to `bool`, and
+`T::operator-=` should return type convertible to `T`). Such "loose"
+requirements make `operators` library applicable to broader set of
+target classes from different domains, i.e. eventually more useful.
+
+[#sec:example]
+[heading Example]
+
+This example shows how some of the [link sec:arithmetic arithmetic
+operator templates] can be used with a geometric point class
+template.
+
+```
+template
+class point // note: private inheritance is OK here!
+: boost::addable< point // point + point
+, boost::subtractable< point // point - point
+, boost::dividable2< point, T // point / T
+, boost::multipliable2< point, 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
+T length(const point p)
+{
+ return sqrt(p.x()*p.x() + p.y()*p.y());
+}
+
+const point right(0, 1);
+const point up(1, 0);
+const point pi_over_4 = up + right;
+const point pi_over_4_normalized = pi_over_4 / length(pi_over_4);
+```
+
+[#sec:usage]
+[heading Usage]
+
+[#sec:two_arg]
+[h5 Two-Argument Template Forms]
+
+[#sec:two_arg_gen]
+
+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 [link sec:example 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 [link table:addable2 `addable`]. The comparison
+templates [link table:less_than_comparable2 `less_than_comparable`],
+[link table:equality_comparable2 `equality_comparable`],
+[link table:equivalent2 `equivalent`], and
+[link table:partially_ordered2 `partially_ordered`] 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 [link sec:chaining base class chaining]
+technique.
+
+[#sec:mixed_arithmetics]
+
+['Mixed Arithmetics]: Another application of the
+ two-argument template forms is for mixed
+arithmetics between a type `T` and a type `U` that
+is convertible to `T`. In this case there are two ways where
+the two-argument template forms are helpful: one is to provide the
+respective signatures for operator overloading, the second is
+performance.
+
+With respect to the operator overloading assume e.g. that
+`U` is `int`, that `T` is an user-defined unlimited integer type,
+and that `double operator-(double, const T&)` exists.
+
+If one wants to compute `int - T` and does not provide
+`T operator-(int, const T&)`, the compiler will consider
+`double operator-(double, const T&)` to be a better match
+than `T operator-(const T&, const T&)`, which will probably
+be different from the user's intention.
+
+To define a complete set of operator signatures, additional 'left'
+forms of the two-argument template forms are provided
+[link table:subtractable2_left `subtractable2_left`],
+[link table:dividable2_left `dividable2_left`], and
+[link table:modable2_left `modable2_left`] that
+define the signatures for non-commutative operators where
+ `U` appears on the left hand side (`operator-(const U&, const T&)`,
+`operator/(const U&, const T&)`, `operator%(const U&, const T&)`).
+
+With respect to the performance observe that when one uses the single
+type binary operator for mixed type arithmetics, the type `U`
+argument has to be converted to type `T`. In practice,
+however, there are often more efficient implementations of, say
+`T::operator-=(const U&)` that avoid unnecessary conversions
+from `U` to `T`.
+
+The two-argument template forms of the arithmetic operator create
+additional operator interfaces that use these more efficient implementations.
+There is, however, no performance gain in the 'left' forms: they still need a
+conversion from `U` to `T` and have an implementation equivalent to the code
+that would be automatically created by the compiler if it considered the
+single type binary operator to be the best match.
+
+[#sec:chaining]
+[h5 Base Class Chaining and Object Size]
+
+Every operator class template, except the [link sec:ex_oprs arithmetic examples]
+and the [link sec:iterator iterator helpers], has an additional, but optional,
+template type parameter `B`. This parameter will be a publicly-derived base class of
+the instantiated template. This means it must be a class type. It can be
+used to avoid the bloating of object sizes that is commonly associated
+with multiple-inheritance from several empty base classes. See the
+[link sec:old_lib_note note for users of older versions] for more
+details.
+
+To provide support for a group of operators, use the
+`B` parameter to chain operator templates into a single-base
+class hierarchy, demostrated in the [link sec:example usage example].
+The technique is also used by the composite operator templates to group
+operator definitions. If a chain becomes too long for the compiler to
+support, try replacing some of the operator templates with a single
+grouped operator template that chains the old templates together; the
+length limit only applies to the number of templates directly in the
+chain, not those hidden in group templates.
+
+['Caveat]: to chain to a base class which is ['not] a Boost operator
+template when using the [link sec:two_arg 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.
+
+[#sec:explicit_instantiation]
+[h5 Separate Explicit Instantiation]
+
+On some compilers (e.g. Borland, GCC) even single-inheritance
+seems to cause an increase in object size in some cases. If you are not
+defining a class template, you may get better object-size performance by
+avoiding derivation altogether, and instead explicitly instantiating the
+operator template as follows:
+
+```
+class my_class // lose the inheritance...
+{
+ //...
+};
+
+// explicitly instantiate the operators I need.
+template struct less_than_comparable;
+template struct equality_comparable;
+template struct incrementable;
+template struct decrementable;
+template struct addable;
+template struct subtractable;
+```
+
+
+
+Note that some operator templates cannot use this workaround and must
+be a base class of their primary operand type. Those templates define
+operators which must be member functions, and the workaround needs the
+operators to be independent `friend` functions. The relevant templates
+are:
+
+* [link table:dereferenceable `dereferenceable<>`]
+* [link table:indexable `indexable<>`]
+* Any composite operator template that includes at least one of the above
+
+As Daniel Krugler pointed out, this technique violates 14.6.5/2 and is thus
+non-portable. The reasoning is, that the operators injected by the instantiation
+of e.g. `less_than_comparable` can not be found by ADL according to the
+rules given by 3.4.2/2, since `my_class` is not an associated class of
+`less_than_comparable`. Thus only use this technique if all else fails.
+
+[#sec:portability]
+[h5 Requirement Portability]
+
+Many compilers (e.g. MSVC 6.3, GCC 2.95.2) will not enforce the
+requirements in the operator template tables unless the operations which
+depend on them are actually used. This is not standard-conforming
+behavior. In particular, although it would be convenient to derive all
+your classes which need binary operators from the [link table:operators1 `operators<>`]
+and [link table:operators2 `operators2<>`] templates, regardless of
+whether they implement all the requirements of those templates, this
+shortcut is not portable. Even if this currently works with your
+compiler, it may not work later.
+
+[#sec:arithmetic]
+[heading Arithmetic Operators]
+
+The arithmetic operator templates ease the task of creating a custom
+numeric type. Given a core set of operators, the templates add related
+operators to the numeric class. These operations are like the ones the
+standard arithmetic types have, and may include comparisons, adding,
+incrementing, logical and bitwise manipulations, etc. Further,
+since most numeric types need more than one of these operators, some
+templates are provided to combine several of the basic operator templates
+in one declaration.
+
+The requirements for the types used to instantiate the simple operator
+templates are specified in terms of expressions which must be valid and
+the expression's return type. The composite operator templates only list
+what other templates they use. The supplied operations and requirements
+of the composite operator templates can be inferred from the operations
+and requirements of the listed components.
+
+[#sec:smpl_oprs]
+[h5 Simple Arithmetic Operators]
+
+These templates are "simple" since they provide operators based on a
+single operation the base type has to provide. They have an additional
+optional template parameter `B`, which is not shown, for the
+[link sec:chaining base class chaining] technique.
+
+The primary operand type `T` needs to be of class type,
+built-in types are not supported.
+
+[table Notation
+ [[Key] [Description]]
+ [[`T`] [primary operand type]]
+ [[`t,t1`] [values of type `T`]]
+ [[`U`] [alternate operand type]]
+ [[`u`] [value of type `U`]]
+]
+
+[table Simple Arithmetic Operator Template Classes
+ [[Template] [Supplied Operations] [Requirements] [Propagates constexpr]]
+ [
+ [
+ [#table:less_than_comparable1] `less_than_comparable`
+
+ __less_than_comparable1__``
+ ]
+
+ [
+ `bool operator>(const T&, const T&)`
+
+ `bool operator<=(const T&, const T&)`
+
+ `bool operator>=(const T&, const T&)`
+ ]
+
+ [
+ `t < t1`.
+
+ Return convertible to `bool`. See the [link sec:ordering Ordering Note]
+ ]
+
+ [
+ Since `C++11`, except [@https://developercommunity.visualstudio.com/content/problem/414193/rejects-valid-constexpr-marked-friend-function-def.html MSVC < v19.22]
+ ]
+ ]
+
+ [
+ [
+ [#table:less_than_comparable2]`less_than_comparable`
+
+ __less_than_comparable2__``
+ ]
+
+ [
+ `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`. `t > u`.
+
+ Returns convertible to `bool`. See the [link sec:ordering Ordering Note].
+ ]
+
+ [
+ Since `C++11`, except [@https://developercommunity.visualstudio.com/content/problem/414193/rejects-valid-constexpr-marked-friend-function-def.html MSVC < v19.22]
+ ]
+ ]
+
+ [
+ [
+ [#table:equality_comparable1]`equality_comparable`
+
+ __equality_comparable1__``
+ ]
+
+ [
+ `bool operator!=(const T&, const T&)`
+ ]
+
+ [
+ `t == t1`.
+
+ Return convertible to `bool`.
+ ]
+
+ [
+ Since `C++11`, except [@https://developercommunity.visualstudio.com/content/problem/414193/rejects-valid-constexpr-marked-friend-function-def.html MSVC < v19.22]
+ ]
+ ]
+
+ [
+ [
+ [#table:equality_comparable2]`equality_comparable`
+
+ __equality_comparable2__``
+ ]
+
+ [
+ `bool operator==(const U&, const T&)`
+
+ `bool operator!=(const U&, const T&)`
+
+ `bool operator!=(const T&, const U&)`
+ ]
+
+ [
+ `t == u`.
+
+ Return convertible to `bool`.
+ ]
+
+ [
+ Since `C++11`, except [@https://developercommunity.visualstudio.com/content/problem/414193/rejects-valid-constexpr-marked-friend-function-def.html MSVC < v19.22]
+ ]
+ ]
+
+ [
+ [
+ [#table:addable1]`addable`
+
+ `addable1`
+ ]
+
+ [
+ `T operator+(const T&, const T&)`
+ ]
+
+ [
+ `T temp(t); temp += t1`.
+
+ Return convertible to `T`. See the [link sec:symmetry Symmetry Note].
+ ]
+
+ [No]
+ ]
+
+ [
+ [
+ [#table:addable2]`addable`
+
+ `addable2`
+ ]
+
+ [
+ `T operator+(const T&, const U&)`
+
+ `T operator+(const U&, const T& )`
+ ]
+
+ [
+ `T temp(t); temp += u`.
+
+ Return convertible to `T`. See the [link sec:symmetry Symmetry Note].
+ ]
+
+ [No]
+ ]
+
+ [
+ [
+ [#table:subtractable1]`subtractable`
+
+ `subtractable1`
+ ]
+
+ [
+ `T operator-(const T&, const T&)`
+ ]
+
+ [
+ `T temp(t); temp -= t1`.
+
+ Return convertible to `T`. See the [link sec:symmetry Symmetry Note].
+ ]
+
+ [No]
+ ]
+
+ [
+ [
+ [#table:subtractable2]`subtractable`
+
+ `subtractable2`
+ ]
+
+ [
+ `T operator-(const T&, const U&)`
+ ]
+
+ [
+ `T temp(t); temp -= u`.
+
+ Return convertible to `T`. See the [link sec:symmetry Symmetry Note].
+ ]
+
+ [No]
+ ]
+
+ [
+ [
+ [#table:subtractable2_left]`subtractable2_left`
+ ]
+
+ [
+ `T operator-(const U&, const T&)`
+ ]
+
+ [
+ `T temp(u); temp -= t`.
+
+ Return convertible to `T`.
+ ]
+
+ [No]
+ ]
+
+ [
+ [
+ [#table:multipliable1]`multipliable`
+
+ `multipliable1`
+ ]
+
+ [
+ `T operator*(const T&, const T&)`
+ ]
+
+ [
+ `T temp(t); temp *= t1`.
+
+ Return convertible to `T`. See the [link sec:symmetry Symmetry Note].
+ ]
+
+ [No]
+ ]
+
+ [
+ [
+ [#table:multipliable2]`multipliable`
+
+ `multipliable2`
+ ]
+
+ [
+ `T operator*(const T&, const U&)`
+
+ `T operator*(const U&, const T&)`
+ ]
+
+ [
+ `T temp(t); temp *= u`.
+
+ Return convertible to `T`. See the [link sec:symmetry Symmetry Note].
+ ]
+
+ [No]
+ ]
+
+ [
+ [
+ [#table:dividable1]`dividable`
+
+ `dividable1`
+ ]
+
+ [
+ `T operator/(const T&, const T&)`
+ ]
+
+ [
+ `T temp(t); temp /= t1`.
+
+ Return convertible to `T`. See the [link sec:symmetry Symmetry Note].
+ ]
+
+ [No]
+ ]
+
+ [
+ [
+ [#table:dividable2]`dividable`
+
+ `dividable2`
+ ]
+
+ [
+ `T operator/(const T&, const U&)`
+ ]
+
+ [
+ `T temp(t); temp /= u`.
+
+ Return convertible to `T`. See the [link sec:symmetry Symmetry Note].
+ ]
+
+ [No]
+ ]
+
+ [
+ [
+ [#table:dividable2_left]`dividable2_left`
+ ]
+
+ [
+ `T operator/(const U&, const T&)`
+ ]
+
+ [
+ `T temp(u); temp /= t`.
+
+ Return convertible to `T`.
+ ]
+
+ [No]
+ ]
+
+ [
+ [
+ [#table:modable1]`modable`
+
+ `modable1`
+ ]
+
+ [
+ `T operator%(const T&, const T&)`
+ ]
+
+ [
+ `T temp(t); temp %= t1`.
+
+ Return convertible to `T`. See the [link sec:symmetry Symmetry Note].
+ ]
+
+ [No]
+ ]
+
+ [
+ [
+ [#table:modable2]`modable`
+
+ `modable2`
+ ]
+
+ [
+ `T operator%(const T&, const U&)`
+ ]
+
+ [
+ `T temp(t); temp %= u`.
+
+ Return convertible to `T`. See the [link sec:symmetry Symmetry Note].
+ ]
+
+ [No]
+ ]
+
+ [
+ [
+ [#table:modable2_left]`modable2_left`
+ ]
+
+ [
+ `T operator%(const U&, const T&)`
+ ]
+
+ [
+ `T temp(u); temp %= t`.
+
+ Return convertible to `T`.
+ ]
+
+ [No]
+ ]
+
+ [
+ [
+ [#table:orable1]`orable`
+
+ `orable1`
+ ]
+
+ [
+ `T operator|(const T&, const T&)`
+ ]
+
+ [
+ `T temp(t); temp |= t1`.
+
+ Return convertible to `T`. See the [link sec:symmetry Symmetry Note].
+ ]
+
+ [No]
+ ]
+
+ [
+ [
+ [#table:orable2]`orable`
+
+ `orable2`
+ ]
+
+ [
+ `T operator|(const T&, const U&)`
+
+ `T operator|(const U&, const T&)`
+ ]
+
+ [
+ `T temp(t); temp |= u`.
+
+ Return convertible to `T`. See the [link sec:symmetry Symmetry Note].
+ ]
+
+ [No]
+ ]
+
+ [
+ [
+ [#table:andable1]`andable`
+
+ `andable1`
+ ]
+
+ [
+ `T operator&(const T&, const T&)`
+ ]
+
+ [
+ `T temp(t); temp &= t1`.
+
+ Return convertible to `T`. See the [link sec:symmetry Symmetry Note].
+ ]
+
+ [No]
+ ]
+
+ [
+ [
+ [#table:andable2]`andable`
+
+ `andable2`
+ ]
+
+ [
+ `T operator&(const T&, const U&)`
+
+ `T operator&(const U&, const T&)`
+ ]
+
+ [
+ `T temp(t); temp &= u`.
+
+ Return convertible to `T`. See the [link sec:symmetry Symmetry Note].
+ ]
+
+ [No]
+ ]
+
+ [
+ [
+ [#table:xorable1]`xorable`
+
+ `xorable1`
+ ]
+
+ [
+ `T operator^(const T&, const T&)`
+ ]
+
+ [
+ `T temp(t); temp ^= t1`.
+
+ Return convertible to `T`. See the [link sec:symmetry Symmetry Note].
+ ]
+
+ [No]
+ ]
+
+ [
+ [
+ [#table:xorable2]`xorable`
+
+ `xorable2`
+ ]
+
+ [
+ `T operator^(const T&, const U&)`
+
+ `T operator^(const U&, const T&)`
+ ]
+
+ [
+ `T temp(t); temp ^= u`.
+
+ Return convertible to `T`. See the [link sec:symmetry Symmetry Note].
+ ]
+
+ [No]
+ ]
+
+ [
+ [
+ [#table:incrementable]`incrementable`
+ ]
+
+ [
+ `T operator++(T&, int)`
+ ]
+
+ [
+ `T temp(t); ++t`
+
+ Return convertible to `T`.
+ ]
+
+ [No]
+ ]
+
+ [
+ [
+ [#table:decrementable]`decrementable`
+ ]
+
+ [
+ `T operator--(T&, int)`
+ ]
+
+ [
+ `T temp(t); --t;`
+
+ Return convertible to `T`.
+ ]
+
+ [No]
+ ]
+
+ [
+ [
+ [#table:left_shiftable1]`left_shiftable`
+
+ `left_shiftable1`
+ ]
+
+ [
+ `T operator<<(const T&, const T&)`
+ ]
+
+ [
+ `T temp(t); temp <<= t1`.
+
+ Return convertible to `T`. See the [link sec:symmetry Symmetry Note].
+ ]
+
+ [No]
+ ]
+
+ [
+ [
+ [#table:left_shiftable2]`left_shiftable`
+
+ `left_shiftable2`
+ ]
+
+ [
+ `T operator<<(const T&, const U&)`
+ ]
+
+ [
+ `T temp(t); temp <<= u`.
+
+ Return convertible to `T`. See the [link sec:symmetry Symmetry Note].
+ ]
+
+ [No]
+ ]
+
+ [
+ [
+ [#table:right_shiftable1]`right_shiftable`
+
+ `right_shiftable1`
+ ]
+
+ [
+ `T operator>>(const T&, const T&)`
+ ]
+
+ [
+ `T temp(t); temp >>= t1`.
+
+ Return convertible to `T`. See the [link sec:symmetry Symmetry Note].
+ ]
+
+ [No]
+ ]
+
+ [
+ [
+ [#table:right_shiftable2]`right_shiftable`
+
+ `right_shiftable2`
+ ]
+
+ [
+ `T operator>>(const T&, const U&)`
+ ]
+
+ [
+ `T temp(t); temp >>= u`.
+
+ Return convertible to `T`. See the [link sec:symmetry Symmetry Note].
+ ]
+
+ [No]
+ ]
+
+ [
+ [
+ [#table:equivalent1]`equivalent`
+
+ __equivalent1__``
+ ]
+
+ [
+ `bool operator==(const T&, const T&)`
+ ]
+
+ [
+ `t < t1`.
+
+ Return convertible to `bool`. See the [link sec:ordering Ordering Note].
+ ]
+
+ [
+ Since `C++11`, except [@https://developercommunity.visualstudio.com/content/problem/414193/rejects-valid-constexpr-marked-friend-function-def.html MSVC < v19.22]
+ ]
+ ]
+
+ [
+ [
+ [#table:equivalent2]`equivalent`
+
+ __equivalent2__``
+ ]
+
+ [
+ `bool operator==(const T&, const U&)`
+ ]
+
+ [
+ `t < u`. `t > u`.
+
+ Returns convertible to `bool`. See the [link sec:ordering Ordering Note].
+ ]
+
+ [
+ Since `C++11`, except [@https://developercommunity.visualstudio.com/content/problem/414193/rejects-valid-constexpr-marked-friend-function-def.html MSVC < v19.22]
+ ]
+ ]
+
+ [
+ [
+ [#table:partially_ordered1]`partially_ordered`
+
+ __partially_ordered1__``
+ ]
+
+ [
+ `bool operator>(const T&, const T&)`
+
+ `bool operator<=(const T&, const T&)`
+
+ `bool operator>=(const T&, const T&)`
+ ]
+
+ [
+ `t < t1`. `t == t1`.
+
+ Returns convertible to `bool`. See the [link sec:ordering Ordering Note].
+ ]
+
+ [
+ Since `C++11`, except [@https://developercommunity.visualstudio.com/content/problem/414193/rejects-valid-constexpr-marked-friend-function-def.html MSVC < v19.22]
+ ]
+ ]
+
+ [
+ [
+ [#table:partially_ordered2]`partially_ordered`
+
+ __partially_ordered2__``
+ ]
+
+ [
+ `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`. `t > u`. `t == u`.
+
+ Returns convertible to `bool`. See the [link sec:ordering Ordering Note].
+ ]
+
+ [
+ Since `C++11`, except [@https://developercommunity.visualstudio.com/content/problem/414193/rejects-valid-constexpr-marked-friend-function-def.html MSVC < v19.22]
+ ]
+ ]
+]
+
+[#sec:ordering]
+['Ordering Note]: The [link table:less_than_comparable1 `less_than_comparable`] and
+[link table:partially_ordered1 `partially_ordered`] templates provide the same set
+of operations. However, the workings of [link table:less_than_comparable1 `less_than_comparable`] assume
+that all values of type `T` can be placed in a total order. If
+that is not true (e.g. Not-a-Number values in IEEE floating point
+arithmetic), then [link table:partially_ordered1 `partially_ordered`] should be
+used. The [link table:partially_ordered1 `partially_ordered`] template can
+be used for a totally-ordered type, but it is not as efficient as
+[link table:less_than_comparable1 `less_than_comparable`]. This
+rule also applies for [link table:less_than_comparable2 `less_than_comparable`] and
+[link table:partially_ordered2 `partially_ordered`] with respect to the ordering
+of all `T` and `U` values, and for both versions of
+[link table:equivalent1 `equivalent<>`]. The solution for
+[link table:equivalent1 `equivalent<>`] is to write a custom
+`operator==` for the target class.
+
+[#sec:symmetry]
+['Symmetry Note]: Before talking about symmetry, we need to talk about optimizations to
+understand the reasons for the different implementation styles of
+operators. Let's have a look at `operator+` for a class
+`T` as an example:
+
+```
+T operator+( const T& lhs, const T& rhs )
+{
+ return T( lhs ) += rhs;
+}
+```
+
+This would be a normal implementation of `operator+`, but it
+is not an efficient one. An unnamed local copy of `lhs` is
+created, `operator+=` is called on it and it is copied to the
+function return value (which is another unnamed object of type
+`T`). The standard doesn't generally allow the intermediate
+object to be optimized away:
+
+["3.7.2/2: Automatic storage duration: If a named automatic object has initialization or a destructor with
+side effects, it shall not be destroyed before the end of its block,
+nor shall it be eliminated as an optimization even if it appears to be
+unused, except that a class object or its copy may be eliminated as
+specified in 12.8.]
+
+The reference to 12.8 is important for us:
+
+["12.8/15: Copying class objects: (...) For a function with a class return type, if the expression in the
+return statement is the name of a local object, and the cv-unqualified
+type of the local object is the same as the function return type, an
+implementation is permitted to omit creating the temporary object to
+hold the function return value, even if the class copy constructor or
+destructor has side effects.]
+
+This optimization is known as the named return value optimization (NRVO),
+which leads us to the following implementation for `operator+`:
+
+```
+T operator+( const T& lhs, const T& rhs )
+{
+ T nrv( lhs );
+ nrv += rhs;
+ return nrv;
+}
+```
+
+Given this implementation, the compiler is allowed to remove the
+intermediate object. Sadly, not all compilers implement the NRVO, some
+even implement it in an incorrect way which makes it useless here.
+Without the NRVO, the NRVO-friendly code is no worse than the original
+code showed above, but there is another possible implementation, which
+has some very special properties:
+
+```
+T operator+( T lhs, const T& rhs )
+{
+ return lhs += rhs;
+}
+```
+
+The difference to the first implementation is that `lhs` is
+not taken as a constant reference used to create a copy; instead,
+`lhs` is a by-value parameter, thus it is already the copy
+needed. This allows another optimization (12.2/2) for some cases.
+
+Consider `a + b + c` where the result of `a + b` is not copied when
+used as `lhs` when adding `c`. This is more efficient than the original
+code, but not as efficient as a compiler using the NRVO. For most people,
+it is still preferable for compilers that don't implement the NRVO, but
+the `operator+` now has a different function signature. Also,
+the number of objects created differs for `(a + b ) + c` and `a + ( b + c )`.
+
+Most probably, this won't be a problem for you, but if your code relies on the function
+signature or a strict symmetric behaviour, you should set
+`BOOST_FORCE_SYMMETRIC_OPERATORS` in your user-config. This
+will force the NRVO-friendly implementation to be used even for compilers
+that do not implement the NRVO.
+
+[#sec:grpd_oprs]
+[h5 Grouped Arithmetic Operators]
+
+The following templates provide common groups of related operations.
+For example, since a type which is addable is usually also subtractable,
+the [link table:additive1 `additive`] template provides the
+combined operators of both. The grouped operator templates have an
+additional optional template parameter `B`, which is not
+shown, for the [link sec:chaining base class chaining] technique.
+
+[table Notation
+ [[Key] [Description]]
+ [[`T`] [primary operand type]]
+ [[`U`] [alternate operand type]]
+]
+
+[table Grouped Arithmetic Operator Template Classes
+ [
+ [Template]
+
+ [Component Operator Templates]
+ ]
+ [
+ [
+ [#table:totally_ordered1] `totally_ordered`
+
+ __totally_ordered1__``
+ ]
+ [
+ [link table:less_than_comparable1 `less_than_comparable`]
+
+ [link table:equality_comparable1 `equality_comparable`]
+ ]
+ ]
+ [
+ [
+ [#table:totally_ordered2]`totally_ordered`
+
+ __totally_ordered2__``
+ ]
+ [
+ [link table:less_than_comparable2 `less_than_comparable`]
+
+ [link table:equality_comparable2 `equality_comparable`]
+ ]
+ ]
+ [
+ [
+ [#table:additive1]`additive`
+
+ __additive1__``
+ ]
+ [
+ [link table:addable1 `addable`]
+
+ [link table:subtractable1 `subtractable`]
+ ]
+ ]
+ [
+ [
+ [#table:additive2]`additive`
+
+ __additive2__``
+ ]
+ [
+ [link table:addable2 `addable`]
+
+ [link table:subtractable2 `subtractable`]
+ ]
+ ]
+ [
+ [
+ [#table:multiplicative1] `multiplicative`
+
+ __multiplicative1__``
+ ]
+ [
+ [link table:multipliable1 `multipliable`]
+
+ [link table:dividable1 `dividable`]
+ ]
+ ]
+ [
+ [
+ [#table:multiplicative2]`multiplicative`
+
+ __multiplicative2__`