From 302e6ba9f988ffe5af75b4293394b9badf2ff7bd Mon Sep 17 00:00:00 2001 From: nobody Date: Fri, 23 Jul 2004 02:16:28 +0000 Subject: [PATCH] This commit was manufactured by cvs2svn to create branch 'SPIRIT_1_6'. [SVN r23968] --- doc/optional.html | 1445 -------------------------- index.html | 9 - test/.cvsignore | 1 - test/Jamfile | 36 - test/Jamfile.v2 | 34 - test/optional_test.cpp | 801 -------------- test/optional_test_common.cpp | 241 ----- test/optional_test_fail1.cpp | 25 - test/optional_test_fail2.cpp | 26 - test/optional_test_fail3.cpp | 33 - test/optional_test_fail3a.cpp | 25 - test/optional_test_fail3b.cpp | 26 - test/optional_test_inplace.cpp | 80 -- test/optional_test_inplace_fail.cpp | 60 -- test/optional_test_inplace_fail2.cpp | 62 -- test/optional_test_ref.cpp | 323 ------ test/optional_test_ref_fail1.cpp | 25 - test/optional_test_ref_fail2.cpp | 23 - test/optional_test_ref_fail3.cpp | 23 - test/optional_test_ref_fail4.cpp | 24 - test/optional_test_tie.cpp | 64 -- 21 files changed, 3386 deletions(-) delete mode 100644 doc/optional.html delete mode 100644 index.html delete mode 100644 test/.cvsignore delete mode 100644 test/Jamfile delete mode 100644 test/Jamfile.v2 delete mode 100644 test/optional_test.cpp delete mode 100644 test/optional_test_common.cpp delete mode 100644 test/optional_test_fail1.cpp delete mode 100644 test/optional_test_fail2.cpp delete mode 100644 test/optional_test_fail3.cpp delete mode 100644 test/optional_test_fail3a.cpp delete mode 100644 test/optional_test_fail3b.cpp delete mode 100644 test/optional_test_inplace.cpp delete mode 100644 test/optional_test_inplace_fail.cpp delete mode 100644 test/optional_test_inplace_fail2.cpp delete mode 100644 test/optional_test_ref.cpp delete mode 100644 test/optional_test_ref_fail1.cpp delete mode 100644 test/optional_test_ref_fail2.cpp delete mode 100644 test/optional_test_ref_fail3.cpp delete mode 100644 test/optional_test_ref_fail4.cpp delete mode 100644 test/optional_test_tie.cpp diff --git a/doc/optional.html b/doc/optional.html deleted file mode 100644 index fd1e2e5..0000000 --- a/doc/optional.html +++ /dev/null @@ -1,1445 +0,0 @@ - - - - - - - -Header - - - -

Header <boost/optional.hpp>

- -

Contents

-
-
Motivation
-
Development
-
Synopsis
-
Semantics
-
Examples
-
Optional references
-
In-Place Factories
-
A note about optional<bool>
-
Exception Safety Guarantees
-
Type requirements
-
Implementation Notes
-
Dependencies and Portability
-
Acknowledgment
-
- -
- -

Motivation

- -

Consider these functions which should return a value but which might not have - a value to return:

-
(A) double sqrt(double n );
-(B) char get_async_input();
-(C) point polygon::get_any_point_effectively_inside();
-

There are different approaches to the issue of not having a value to return.

-

A typical approach is to consider the existence of a valid return value as - a postcondition, so that if the function cannot compute the value to return, - it has either undefined behavior (and can use asssert in a debug build) - or uses a runtime check and throws an exception if the postcondition is violated. - This is a reasonable choice for example, for function (A), because the - lack of a proper return value is directly related to an invalid parameter (out - of domain argument), so it is appropriate to require the callee to supply only - parameters in a valid domain for execution to continue normally.

-

However, function (B), because of its asynchronous nature, does not fail just - because it can't find a value to return; so it is incorrect to consider - such a situation an error and assert or throw an exception. This function must - return, and somehow, must tell the callee that it is not returning a meaningful - value.

-

A similar situation occurs with function (C): it is conceptually an error to - ask a null-area polygon to return a point inside itself, but in many - applications, it is just impractical for performance reasons to treat this as - an error (because detecting that the polygon has no area might be too expensive - to be required to be tested previously), and either an arbitrary point (typically - at infinity) is returned, or some efficient way to tell the callee that there - is no such point is used.

-

There are various mechanisms to let functions communicate that the returned - value is not valid. One such mechanism, which is quite common since it has zero - or negligible overhead, is to use a special value which is reserved to communicate - this. Classical examples of such special values are EOF, string::npos, points - at infinity, etc...

-

When those values exist, i.e. the return type can hold all meaningful values - plus the signal value, this mechanism is quite appropriate and - well known. Unfortunately, there are cases when such values do not exist. In - these cases, the usual alternative is either to use a wider type, such as 'int' - in place of 'char'; or a compound type, such as std::pair<point,bool>. -

-

Returning a std::pair<T,bool>, thus attaching a boolean flag to the result - which indicates if the result is meaningful, has the advantage that can be turned - into a consistent idiom since the first element of the pair can be whatever - the function would conceptually return. For example, the last two functions - could have the following interface:

-
std::pair<char,bool> get_async_input();
-std::pair<point,bool> polygon::get_any_point_effectively_inside();
-

These functions use a consistent interface for dealing with possibly inexistent - results:

-
std::pair<point,bool> p = poly.get_any_point_effectively_inside();
-if ( p.second )
-  flood_fill(p.first);
-
- -

However, not only is this quite a burden syntactically, it is also error - prone since the user can easily use the function result (first element of the - pair) without ever checking if it has a valid value.

-

Clearly, we need a better idiom.

- -

Development

- -

The models:

-

In C++, we can declare an object (a variable) of type T, and we can give this variable - an initial value (through an initializer. (c.f. 8.5)).
- When a declaration includes a non-empty initializer (an initial value is given), it is said that - the object has been initialized.
- If the declaration uses an empty initializer (no initial value is given), - and neither default nor value initialization applies, it is said that the object is - uninitialized. Its actual value exist but has an - indeterminate inital value (c.f. 8.5.9).
- optional<T> intends to formalize the notion of initialization/no-initialization - allowing a program to test whether an object has been initialized and stating that access to - the value of an uninitialized object is undefined behaviour. That is, - when a variable is declared as optional<T> and no initial value is given, - the variable is formally uninitialized. A formally uninitialized optional object has conceptually - no value at all and this situation can be tested at runtime. It is formally undefined behaviour - to try to access the value of an uninitialized optional. An uninitialized optional can be assigned a value, in which case its initialization state changes to initialized. Furthermore, given the formal - treatment of initialization states in optional objects, it is even possible to reset an optional to uninitialized.

-

In C++ there is no formal notion of uninitialized objects, which - means that objects always have an initial value even if indeterminate.
- As discussed on the previous section, this has a drawback because you need additional - information to tell if an object has been effectively initialized.
- One of the typical ways in which this has been historically - dealt with is via a special value: EOF,npos,-1, etc... This is equivalent to adding - the special value to the set of possible values of a given type. This super set of - T plus some nil_t—were nil_t is some stateless POD—can be modeled in modern - languages as a discriminated union of T and nil_t. - Discriminated unions are often called variants. A variant has a current type, - which in our case is either T or nil_t.
- Using the Boost.Variant library, this model can be implemented - in terms of boost::variant<T,nil_t>.
- There is precedence for a discriminated union as a model for an optional value: the - Haskell Maybe builtin type constructor, - thus a discriminated union T+nil_t serves as a conceptual foundation.

-

A variant<T,nil_t> follows naturally from the traditional idiom of extending -the range of possible values adding an additional sentinel value with the special meaning of Nothing. -However, this additional Nothing value is largely irrelevant for our purpose - since our goal is to formalize the notion of uninitialized objects and, while a special extended value can be used to convey that meaning, it is not strictly neccesary in order to do so.

-

The observation made in the last paragraph about the irrelevant nature of the additional nil_t with respect to -purpose of optional<T> suggests -an alternative model: a container that either has a value of T or nothing. -

-

As of this writting I don't know of any precedence for a variable-size fixed-capacity (of 1) -stack-based container model for optional values, yet I believe this is the consequence of -the lack of practical implementations of such a container rather than an inherent shortcoming -of the container model.

-

In any event, both the discriminated-union or the single-element container models serve as a conceptual -ground for a class representing optional—i.e. possibly uninitialized—objects.
-For instance, these models show the exact semantics required for a wrapper of optional values:

-

Discriminated-union:

-
-
  • deep-copy semantics: copies of the variant implies copies of the value.
  • -
  • deep-relational semantics: comparisons between variants matches both current types and values
  • -
  • If the variant's current type is T, it is modeling an initialized optional.
  • -
  • If the variant's current type is not T, it is modeling an uninitialized optional.
  • -
  • Testing if the variant's current type is T models testing if the optional is initialized
  • -
  • Trying to extract a T from a variant when its current type is not T, models the undefined behaviour -of trying to access the value of an uninitialized optional
  • -
    -

    Single-element container:

    -
    -
  • deep-copy semantics: copies of the container implies copies of the value.
  • -
  • deep-relational semantics: comparisons between containers compare container size and if match, contained value
  • -
  • If the container is not empty (contains an object of type T), it is modeling an initialized optional.
  • -
  • If the container is empty, it is modeling an uninitialized optional.
  • -
  • Testing if the container is empty models testing if the optional is initialized
  • -
  • Trying to extract a T from an empty container models the undefined behaviour -of trying to access the value of an uninitialized optional
  • -
    - -

    The semantics:

    -

    Objects of type optional<T> are intended to be used in places where objects of type T would -but which might be uninitialized. Hence, optional<T>'s purpose is to formalize the -additional possibly uninitialized state.
    -From the perspective of this role, optional<T> can have the same operational semantics of T -plus the additional semantics corresponding to this special state.
    -As such, optional<T> could be thought of as a supertype of T. Of course, -we can't do that in C++, so we need to compose the desired semantics using a different mechanism.
    -Doing it the other way around, that is, making optional<T> a subtype of T is not only -conceptually wrong but also impractical: it is not allowed to derive from a non-class type, such as a builtin type.

    - -

    We can draw from the purpose of optional<T> the required basic semantics:

    - -
    -

    Default Construction: To introduce a formally uninitialized wrapped -object.

    - -

    Direct Value Construction via copy: To introduce a formally -initialized wrapped object whose value is obtained as a copy of some object.

    - -

    Deep Copy Construction: To obtain a different yet equivalent wrapped -object.

    - -

    Direct Value Assignment (upon initialized): To assign the wrapped object a value obtained -as a copy of some object.

    - -

    Direct Value Assignment (upon uninitialized): To initialize the wrapped object -with a value obtained -as a copy of some object.

    - -

    Assignnment (upon initialized): To assign the wrapped object a value obtained as a copy -of another wrapper's object.

    - -

    Assignnment (upon uninitialized): To initialize the wrapped object -with value obtained as a copy -of another wrapper's object.

    - -

    Deep Relational Operations (when supported by the type T): To compare -wrapped object values taking into account the presence of uninitialized -operands.

    - -

    Value access: To unwrap the wrapped object.

    - -

    Initialization state query: To determine if the object is formally -initialized or not.

    - -

    Swap: To exchange wrapper's objects. (with whatever exception safety -guarantiees are provided by T's swap).

    - -

    De-initialization: To release the wrapped object (if any) and leave -the wrapper in the uninitialized state.

    - -
    - -

    Additional operations are useful, such as converting constructors and -converting assignments, in-place construction and assignment, and safe value -access via a pointer to the wrapped object or null.

    -

    The Interface:

    -

    Since the purpose of optional is to allow us to use objects with a formal -uninitialized additional state, the interface could try to follow the interface -of the underlying T type as much as possible. In order to choose the proper -degree of adoption of the native T interface, the following must be noted:
    -Even if all the operations supported by an instance of type T are defined for -the entire range of values for such a type, an optional<T> extends such a set of -values with a new value for which most (otherwise valid) operations are not -defined in terms of T.
    -Furthermore, since optional<T> itself is merely a T wrapper (modeling a T -supertype), any attempt to define such operations upon uninitialized optionals -will be totally artificial w.r.t. T.
    -This library chooses an interface which follows from T's interface only for -those operations which are well defined (w.r.t the type T) even if any of the -operands are uninitialized. These operations include: construction, -copy-construction, assignment, swap and relational operations.
    -For the value access operations, which are undefined (w.r.t the type T) when the -operand is uninitialized, a different interface is choosen (which will be -explained next).
    -Also, the presence of the possibly uninitialized state requires additional -operations not provided by T itself which are supported by a special interface.

    -

    Lexically-hinted Value Access in the presence of possibly untitialized -optional objects: The operators * and ->

    -

    A relevant feature of a pointer is that it can have a null - pointer value. This is a special value which is used to indicate that the - pointer is not referring to any object at all. In other words, null pointer - values convey the notion of inexistent objects.

    -

    This meaning of the null pointer value allowed pointers to became a de facto standard - for handling optional objects because all you have to do to refer to a value which you - don't really have is to use a null pointer value of the appropriate type. - Pointers have been used for decades—from the days of C APIs to modern C++ libraries—to - refer to optional (that is, possibly inexistent) objects; particularly - as optional arguments to a function, but also quite often as optional data members.

    -

    The possible presence of a null pointer value makes the operations that access the - pointee's value possibly undefined, therefore, expressions which use dereference - and access operators, such as: ( *p = 2 ) and ( p->foo()), - implicitly convey the notion of optionality, and this information is tied to - the syntax of the expressions. That is, the presence of operators * and -> tell by - themselves—without any additional context—that the expression will be undefined unless - the implied pointee actually exist.

    -

    Such a de facto idiom for referring to optional objects can be formalized in the form of a -concept: the OptionalPointee concept.
    -This concept captures the syntactic usage of operatos *, -> and conversion to bool to convey -the notion of optionality.

    -

    However, pointers are good to refer to optional objects, but not particularly good -to handle the optional objects in all other respects, such as initializing or moving/copying -them. The problem resides in the shallow-copy of pointer semantics: if you need to - effectively move or copy the object, pointers alone are not enough. The problem - is that copies of pointers do not imply copies of pointees. For example, as - was discussed in the motivation, pointers alone cannot be used to return optional - objects from a function because the object must move outside from the function and - into the caller's context.
    - A solution to the shallow-copy problem that is often used is to resort to dynamic - allocation and use a smart pointer to automatically handle the details of this. - For example, if a function is to optionally return an object X, it can use shared_ptr<X> - as the return value. However, this requires dynamic allocation of X. If X is - a builtin or small POD, this technique is very poor in terms of required resources. - Optional objects are essentially values so it is very convenient to be able to use automatic - storage and deep-copy semantics to manipulate optional values just as we do with ordinary - values. Pointers do not have this semantics, so are unappropriate for the initialization and - transport of optional values, yet are quite convenient for handling the access to the - possible undefined value because of the idiomatic aid present in the OptionalPointee - concept incarnated by pointers. -

    -

    Optional<T> as a model of OptionalPointee

    -

    For value access operations optional<> uses operators * and -> to lexically -warn about the possibliy uninitialized state appealing to the familiar pointer -semantics w.r.t. to null pointers.
    -However, it is particularly important to note that optional<> objects are not pointers. optional<> -is not, and does not model, a pointer. -

    For instance, optional<> has not shallow-copy so does not alias: two different optionals - never refer to the same value unless T itself is an reference (but my have equivalent values).
    - The difference between an optional<T> and a pointer must be kept in mind, particularly - because the semantics of relational operators are different: since optional<T> - is a value-wrapper, relational operators are deep: they compare optional values; - but relational operators for pointers are shallow: they do not compare pointee values.
    - As a result, you might be able to replace optional<T> by T* on some situations but - not always. Specifically, on generic code written for both, you cannot use relational - operators directly, and must use the template functions - equal_pointees() and - less_pointees() instead. -


    - -

    Synopsis

    - -
    namespace boost {
    -
    -template<class T>
    -class optional
    -{
    -  public :
    -
    -    (If T is of reference type, the parameters and results by reference are by value)
    -
    -    optional () ;
    -
    -    optional ( detail::none_t ) ;
    -
    -    optional ( T const& v ) ; 
    -
    -    optional ( optional const& rhs ) ; 
    -
    -    template<class U> explicit optional ( optional<U> const& rhs ) ;
    -    
    -    template<class InPlaceFactory> explicit optional ( InPlaceFactory const& f ) ;
    -    
    -    template<class TypedInPlaceFactory> explicit optional ( TypedInPlaceFactory const& f ) ;
    -
    -    optional& operator = ( detail::none_t ) ;
    -    
    -    optional& operator = ( T const& v ) ; 
    -
    -    optional& operator = ( optional const& rhs ) ;
    -
    -    template<class U> optional& operator = ( optional<U> const& rhs ) ;
    -
    -    template<class InPlaceFactory> optional& operator = ( InPlaceFactory const& f ) ;
    -    
    -    template<class TypedInPlaceFactory> optional& operator = ( TypedInPlaceFactory const& f ) ;
    -    
    -    T const& get() const ; 
    -    T&       get() ;       
    -
    -    T const* operator ->() const ;
    -    T*       operator ->() ;
    -
    -    T const& operator *() const ;
    -    T&       operator *() ;
    -
    -    T const* get_ptr() const ;
    -    T*       get_ptr() ;
    -
    -    operator unspecified-bool-type() const ;
    -
    -    bool operator!() const ;
    -    
    -    deprecated methods
    -    
    -    void reset() ; (deprecated)
    -    void reset ( T const& ) ; (deprecated)
    -    bool is_initialized() const ; (deprecated)
    -
    -} ;
    -
    -template<class T> inline bool operator == ( optional<T> const& x, optional<T> const& y ) ;
    -
    -template<class T> inline bool operator != ( optional<T> const& x, optional<T> const& y ) ;
    -
    -template<class T> inline bool operator <  ( optional<T> const& x, optional<T> const& y ) ;
    -
    -template<class T> inline bool operator >  ( optional<T> const& x, optional<T> const& y ) ;
    -
    -template<class T> inline bool operator <= ( optional<T> const& x, optional<T> const& y ) ;
    -
    -template<class T> inline bool operator >= ( optional<T> const& x, optional<T> const& y ) ;
    -
    -template<class T> inline T const& get ( optional<T> const& opt ) ;
    -
    -template<class T> inline T& get ( optional<T> & opt ) ;
    -
    -template<class T> inline T const* get ( optional<T> const* opt ) ;
    -
    -template<class T> inline T* get ( optional<T>* opt ) ;
    -
    -template<class T> inline T const* get_pointer ( optional<T> const& opt ) ;
    -
    -template<class T> inline T* get_pointer ( optional<T> & opt ) ;
    -
    -template<class T> inline void swap( optional<T>& x, optional<T>& y ) ;
    -
    -} // namespace boost
    -
    - -
    - -

    Detailed Semantics

    - -

    NOTES:

    - -

    Because T might be of reference type, in the sequel, those entries whose -semantic depends on T being of reference type or not will be distinguished using -the following convention:
    -If the entry reads: optional<T (not a ref)>, the description corresponds only to -the case where T is not of reference type.
    -If the entry reads: optional<T&>, the description corresponds only to the case -where T is of reference type.
    -If the entry reads: optional<T>, the description is the same for both cases.

    - -

    The following section contains various assert() which are used only to -show the postconditions as sample code. It is not implied that the type T must -support each particular expression but that if the expression is supported, the -implied condition holds.

    - -
    - -
    optional<T>::optional();
    -
    -

    Effect: Default-Constructs an optional.

    -

    Postconditions: *this is uninitialized.

    -

    Throws: Nothing.

    -

    Notes: T's default constructor is not called.

    -

    Example:

    -
    -
    optional<T> def ;
    -assert ( !def ) ;
    -
    -
    - -
    - -
    optional<T>::optional( detail::none_t );
    -
    -

    Effect: Constructs an optional uninitialized.

    -

    Postconditions: *this is uninitialized.

    -

    Throws: Nothing.

    -

    Notes:

    -
    -

    T's default constructor is not called.
    -The -expression boost::none denotes an instance of boost::detail::none_t that can be -used as the parameter.

    -
    -

    Example:

    -
    -
    optional<T> n(none) ;
    -assert ( !n ) ;
    -
    -
    - -
    - -
    optional<T (not a ref)>::optional( T const& v )
    -
    -

    Effect: Directly-Constructs an optional.

    - -

    Postconditions: *this is initialized and its value is a copy of 'v'.

    -

    Throws: Whatever T::T( T const& ) throws.

    -

    Notes: T::T( T const& ) is called.

    -

    Exception Safety: Exceptions can only be thrown during T::T( T const& ); -in that case, this constructor has no effect. -

    -

    Example:

    -
    -
    T v;
    -optional<T> opt(v);
    -assert ( *opt == v ) ;
    -
    -
    - -
    - -
    optional<T&>::optional( T ref )
    -
    -

    Effect: Directly-Constructs an optional.

    -

    Postconditions: *this is initialized and its value is an -instance of an internal type wrapping the reference 'ref'.

    -

    Throws: Nothing.

    -

    Example:

    -
    -
    T v;
    -T& vref = v ;
    -optional<T&> opt(vref);
    -assert ( *opt == v ) ;
    -++ v ; // mutate referee
    -assert (*opt == v); 
    -
    -
    - -
    - -
    optional<T (not a ref)>::optional( optional const& rhs );
    -
    -

    Effect: Copy-Constructs an optional.

    -

    Postconditions: If rhs is initialized, *this is initialized -and its value is a copy of the value of rhs; else *this -is uninitialized.

    -

    Throws: Whatever T::T( T const& ) throws.

    -

    Notes: If rhs is initialized, T::T(T const& ) is called.

    -

    Exception Safety: Exceptions can only be thrown during T::T( T const& ); -in that case, this constructor has no effect. -

    -

    Example:

    -
    -
    optional<T> uninit ;
    -assert (!uninit);
    -
    -optional<T> uinit2 ( uninit ) ;
    -assert ( uninit2 == uninit );
    -
    -optional<T> init( T(2) );
    -assert ( *init == T(2) ) ;
    -
    -optional<T> init2 ( init ) ;
    -assert ( init2 == init ) ;
    -
    - -
    -
    - -
    - -
    optional<T&>::optional( optional const& rhs );
    -
    -

    Effect: Copy-Constructs an optional.

    -

    Postconditions: If rhs is initialized, *this is initialized -and its value is a copy of the internal wrapper holding the references in rhs; else *this -is uninitialized.

    -

    Throws: Nothing.

    -

    Notes: If rhs is initialized, the internal wrapper will be -copied and just like true references, both *this and rhs will -referr to the same object (will alias).

    -

    Example:

    -
    -
    optional<T&> uninit ;
    -assert (!uninit);
    -
    -optional<T&> uinit2 ( uninit ) ;
    -assert ( uninit2 == uninit );
    -
    -T v = 2 ; T& ref = v ;
    -optional<T> init(ref);
    -assert ( *init == v ) ;
    -
    -optional<T> init2 ( init ) ;
    -assert ( *init2 == v ) ;
    -
    - -
    -
    - -
    - -
    template<U> explicit optional<T (not a ref)>::optional( optional<U> const& rhs );
    -
    -

    Effect: Copy-Constructs an optional.

    -

    Postconditions: If rhs is initialized, *this is initialized - and its value is a copy of the value of rhs converted - to type T; else *this is uninitialized. -

    -

    Throws: Whatever T::T( U const& ) throws.

    -

    Notes: T::T( U const& ) is called if rhs is initialized, which requires -a valid conversion from U to T. -

    -

    Exception Safety: Exceptions can only be thrown during T::T( U const& ); -in that case, this constructor has no effect. -

    -

    Example:

    -
    - -
    optional<double> x(123.4);
    -assert ( *x == 123.4 ) ;
    -
    -optional<int> y(x) ;
    -assert( *y == 123 ) ;
    -
    -
    -
    - -
    - -
    template<InPlaceFactory> explicit optional<T (not a ref)>::optional( InPlaceFactory const& f );
    - -
    template<TypedInPlaceFactory> explicit optional<T (not a ref)>::optional( TypedInPlaceFactory const& f );
    -
    -

    Effect: Constructs an optional with a value of T obtained from -the factory.

    -

    Postconditions:  *this is initialized and its value is -directly given from the factory 'f' (i.e, the value is not copied).

    -

    Throws: Whatever the T constructor called by the factory throws.

    -

    Notes: See In-Place Factories

    -

    Exception Safety: Exceptions can only be thrown during the call to the -T constructor used by the factory; -in that case, this constructor has no effect. -

    -

    Example:

    -
    - -
    class C { C ( char, double, std::string ) ; } ;
    -
    -C v('A',123.4,"hello");
    -
    -optional<C> x( in_place   ('A', 123.4, "hello") ); // InPlaceFactory used
    -optional<C> y( in_place<C>('A', 123.4, "hello") ); // TypedInPlaceFactory used
    -
    -assert ( *x == v ) ;
    -assert ( *y == v ) ;
    -
    -
    -
    -
    - -
    - -
    optional& optional<T (not a ref)>::operator= ( T const& rhs ) ;
    -
    -

    Effect: Assigns the value 'rhs' to an optional.

    -

    Postconditions: *this is initialized -and its value is a copy of rhs.

    -

    Throws: Whatever T::T( T const& ) throws.

    -

    Notes: If *this was initialized, it is first reset to uninitialized -using T::~T(), then T::T(rhs) is called.

    -

    Exception Safety: Basic: Exceptions can only be thrown during T::T( T const& ); -in that case, *this is left uninitialized. -

    -

    Example:

    -
    -
    T x;
    -optional<T> opt(x) ;
    -
    -T y;
    -opt = y ;
    -assert ( *opt == y ) ;
    -// previous value (copy of 'v') destroyed from within 'opt'.
    -
    -
    -
    -
    - -
    - -
    optional& optional<T (not a ref)>::operator= ( optional const& rhs ) ;
    -
    -

    Effect: Assigns another optional to an optional.

    -

    Postconditions: If rhs is initialized, *this is initialized -and its value is a copy of the value of rhs; else *this -is uninitialized. -

    -

    Throws: Whatever T::T( T const& ) throws.

    -

    Notes: If *this was initialized, it is first reset to uninitialized -using T::~T(), then T::T( T const& ) is called if rhs is initialized. -

    -

    Exception Safety: Basic: Exceptions can only be thrown during T::T( T const& ); -in that case, *this is left uninitialized. -

    -

    Example:

    -
    -
    T v;
    -optional<T> opt(v);
    -optional<T> uninit ;
    -
    -opt = uninit ;
    -assert ( !opt ) ;
    -// previous value (copy of 'v') destroyed from within 'opt'.
    -
    -
    -
    -
    - -
    - -
    template<U> optional& optional<T (not a ref)>::operator= ( optional<U> const& rhs ) ;
    -
    -

    Effect: Assigns another convertible optional to an optional.

    -

    Postconditions: If rhs is initialized, *this is initialized -and its value is a copy of the value of rhs converted -to type T; else *this is uninitialized. -

    -

    Throws: Whatever T::T( U const& ) throws.

    -

    Notes: If *this was initialized, it is first reset to uninitialized -using T::~T(), then T::T( U const& ) is called if rhs is initialized, -which requires a valid conversion from U to T. -

    -

    Exception Safety: Basic: Exceptions can only be thrown during T::T( U const& ); -in that case, *this is left uninitialized. -

    -

    Example:

    -
    -
    T v;
    -optional<T> opt0(v);
    -optional<U> opt1;
    -
    -opt1 = opt0 ;
    -assert ( *opt1 == static_cast<U>(v) ) ;
    -
    -
    -
    - -
    -
    void optional<T (not a ref)>::reset( T const& v ) ;
    -
    -

    Deprecated: same as operator= ( T const& v) ;

    -
    - -
    -
    void optional<T>::reset() ;
    -
    -

    Deprecated: Same as operator=( detail::none_t );

    -
    - -
    - - -
    T const& optional<T (not a ref)>::operator*() const ;
    -T&       optional<T (not a ref)>::operator*();
    - -
    T const& optional<T (not a ref)>::get() const ;
    -T&       optional<T (not a ref)>::get() ;
    -
    -inline T const& get ( optional<T (not a ref)> const& ) ;
    -inline T&       get ( optional<T (not a ref)> &) ;
    -
    -
    -

    Requirements: *this is initialized

    -

    Returns: A reference to the contained value

    -

    Throws: Nothing.

    -

    Notes: The requirement is asserted via BOOST_ASSERT().

    -

    Example:

    -
    -
    T v ;
    -optional<T> opt ( v );
    -T const& u = *opt;
    -assert ( u == v ) ;
    -T w ;
    -*opt = w ;
    -assert ( *opt == w ) ;
    -
    -
    -
    
    -
    - -
    - - -
    T const& optional<T&>::operator*() const ;
    -T      & optional<T&>::operator*();
    - -
    T const& optional<T&>::get() const ;
    -T&       optional<T&>::get() ;
    -
    -inline T const& get ( optional<T&> const& ) ;
    -inline T&       get ( optional<T&> &) ;
    -
    -
    -

    Requirements: *this is initialized

    -

    Returns: The reference contained.

    -

    Throws: Nothing.

    -

    Notes: The requirement is asserted via BOOST_ASSERT().

    -

    Example:

    -
    -
    T v ;
    -T& vref = v ;
    -optional<T&> opt ( vref );
    -T const& vref2 = *opt;
    -assert ( vref2 == v ) ;
    -++ v ;
    -assert ( *opt == v ) ;
    -
    -
    - -
    - -
    T const* optional<T (not a ref)>::get_ptr() const ;
    -T*       optional<T (not a ref)>::get_ptr() ;
    -
    -inline T const* get_pointer ( optional<T (not a ref)> const& ) ;
    -inline T*       get_pointer ( optional<T (not a ref)> &) ;
    -
    -
    -

    Returns: If *this is initialized, a pointer to the contained -value; else 0 (null). -

    -

    Throws: Nothing.

    -

    Notes: The contained value is permanently stored within *this, so -you should not hold nor delete this pointer -

    -

    Example:

    -
    -
    T v;
    -optional<T> opt(v);
    -optional<T> const copt(v);
    -T* p = opt.get_ptr() ;
    -T const* cp = copt.get_ptr();
    -assert ( p == get_pointer(opt) );
    -assert ( cp == get_pointer(copt) ) ;
    -
    -
    -
    - - -
    - - -
    T const* optional<T (not a ref)>::operator ->() const ;
    -T*       optional<T (not a ref)>::operator ->()       ;
    -
    -
    -

    Requirements: *this is initialized.

    -

    Returns: A pointer to the contained value.

    -

    Throws: Nothing.

    -

    Notes: The requirement is asserted via BOOST_ASSERT().

    -

    Example:

    -
    -
    struct X { int mdata ; } ;
    -X x ;
    -optional<X> opt (x);
    -opt->mdata = 2 ;
    -
    -
    -
    - - -
    - - -
    optional<T>::operator unspecified-bool-type() const ;
    -
    -

    Returns: An unspecified value which if used on a boolean context is equivalent to (get() != 0)

    -

    Throws: Nothing.

    -
    -
    optional<T> def ;
    -assert ( def == 0 );
    -optional<T> opt ( v ) ;
    -assert ( opt );
    -assert ( opt != 0 );
    -
    -
    -
    - -
    - - -
     bool optional<T>::operator!() ;
    -
    -

    Returns: If *this is uninitialized, true; else false.

    -

    Throws: Nothing.

    -

    Notes: This operator is provided for those compilers which can't use -the unspecified-bool-type operator in certain boolean contexts. -

    -

    Example:

    -
    -
    optional<T> opt ;
    -assert ( !opt );
    -*opt = some_T ;
    -
    -// Notice the "double-bang" idiom here.
    -assert ( !!opt ) ;
    -
    -
    -
    - - -
    - - -
    bool optional<T>::is_initialized() const ;
    -
    -

    Returns: true is the optional is initialized, false -otherwise.

    -

    Throws: Nothing.

    -
    -
    optional<T> def ;
    -assert ( !def.is_initialized() );
    -optional<T> opt ( v ) ;
    -assert ( opt.is_initialized() );
    -
    -
    - -
    - - -
    bool operator == ( optional<T> const& x, optional<T> const& y );
    -
    -

    Returns: If both x and y are initialied, (*x == *y). -If only x or y is initialized, false. If both are uninitialized, true. -

    -

    Throws: Nothing.

    -

    Notes: Pointers have shallow relational operators while optional has -deep relational operators. Do not use operator == directly in generic code -which expect to be given either an optional<T> or a pointer; -use equal_pointees() instead -

    -

    Example:

    -
    -
    T x(12);
    -T y(12);
    -T z(21);
    -optional<T> def0 ;
    -optional<T> def1 ;
    -optional<T> optX(x);
    -optional<T> optY(y);
    -optional<T> optZ(z);
    -
    -// Identity always hold
    -assert ( def0 == def0 );
    -assert ( optX == optX );
    -
    -// Both uninitialized compare equal
    -assert ( def0 == def1 );
    -
    -// Only one initialized compare unequal.
    -assert ( def0 != optX );
    -
    -// Both initialized compare as (*lhs == *rhs)
    -assert ( optX == optY ) ;
    -assert ( optX != optZ ) ;
    -
    -
    -
    - -
    - - -
    bool operator < ( optional<T> const& x, optional<T> const& y );
    -
    -

    Returns: If y is not initialized, false. -If y is initialized and x is not initialized, true. -If both x and y are initialized, (*x < *y). -

    -

    Throws: Nothing.

    -

    Notes: Pointers have shallow relational operators while optional has -deep relational operators. Do not use operator < directly in generic code -which expect to be given either an optional<T> or a pointer; -use less_pointees() instead -

    -

    Example:

    -
    -
    T x(12);
    -T y(34);
    -optional<T> def ;
    -optional<T> optX(x);
    -optional<T> optY(y);
    -
    -// Identity always hold
    -assert ( !(def < def) );
    -assert ( optX == optX );
    -
    -// Both uninitialized compare equal
    -assert ( def0 == def1 );
    -
    -// Only one initialized compare unequal.
    -assert ( def0 != optX );
    -
    -// Both initialized compare as (*lhs == *rhs)
    -assert ( optX == optY ) ;
    -assert ( optX != optZ ) ;
    -
    -
    -
    - -
    -
    bool operator != ( optional<T> const& x, optional<T> const& y );
    -
    -
    -

    Returns: !( x == y );

    -

    Throws: Nothing.

    -
    - -
    -
    bool operator > ( optional<T> const& x, optional<T> const& y );
    -
    -
    -

    Returns: !( y < x );

    -

    Throws: Nothing.

    -
    - -
    -
    bool operator <= ( optional<T> const& x, optional<T> const& y );
    -
    -
    -

    Returns: !( y<x );

    -

    Throws: Nothing.

    -
    - -
    -
    bool operator >= ( optional<T> const& x, optional<T> const& y );
    -
    -
    -

    Returns: !( x<y );

    -

    Throws: Nothing.

    -
    - -
    - -
    void swap ( optional<T>& x, optional<T>& y );
    - -
    -

    Effect: If both x and y are initialized, calls swap(*x,*y) -using std::swap.
    -If only one is initialized, say x, calls: y.reset(*x); x.reset();
    -If none is initialized, does nothing. -

    -

    Postconditions: The states of x and y interchanged.

    -

    Throws: If both are initialized, whatever swap(T&,T&) throws. -If only one is initialized, whatever T::T ( T const& ) throws. -

    -

    Notes: If both are initialized, swap(T&,T&) is used unqualified -but with std::swap introduced in scope.
    -If only one is initialized, T::~T() and T::T( T const& ) is called. -

    -

    Exception Safety: If both are initialized, this operation has the exception -safety guarantees of swap(T&,T&).
    -If only one is initialized, it has the same basic guarantee as optional<T>::reset( T const& ). -

    -

    Example:

    -
    -
    T x(12);
    -T y(21);
    -optional<T> def0 ;
    -optional<T> def1 ;
    -optional<T> optX(x);
    -optional<T> optY(y);
    -
    -boost::swap(def0,def1); // no-op
    -
    -boost::swap(def0,optX);
    -assert ( *def0 == x );
    -assert ( !optX );
    -
    -boost::swap(def0,optX); // Get back to original values
    -
    -boost::swap(optX,optY);
    -assert ( *optX == y );
    -assert ( *optY == x );
    -
    -
    -
    -
    -
    - -

    Examples

    - -

    Optional return values

    -
    optional<char> get_async_input()
    -{
    -  if ( !queue.empty() )
    -       return optional<char>(queue.top());
    -  else return optional<char>(); // uninitialized
    -}
    -
    -void receive_async_message()
    -{
    -  optional<char> rcv ;
    -  // The safe boolean conversion from 'rcv' is used here.
    -  while ( (rcv = get_async_input()) && !timeout() )
    -    output(*rcv);
    -}
    -
    - -

    Optional local variables

    -
    optional<string> name ;
    -if ( database.open() )
    -{
    -  name.reset ( database.lookup(employer_name) ) ;
    -}
    -else
    -{
    -  if ( can_ask_user )
    -    name.reset ( user.ask(employer_name) ) ;
    -}
    -
    -if ( name )
    -     print(*name);
    -else print("employer's name not found!");
    -
    - -

    Optional data members

    -
    class figure
    -{
    -  public:
    -
    -    figure()
    -    {
    -      // data member 'm_clipping_rect' is uninitialized at this point.
    -    }
    -
    -    void clip_in_rect ( rect const& rect )
    -      {
    -         ....
    -         m_clipping_rect.reset ( rect ) ; // initialized here.
    -      }
    -
    -    void draw ( canvas& cvs )
    -      {
    -        if ( m_clipping_rect )
    -          do_clipping(*m_clipping_rect);
    -
    -        cvs.drawXXX(..);
    -      }
    -
    -    // this can return NULL.
    -    rect const* get_clipping_rect() { return get_pointer(m_clipping_rect); }
    -
    -  private :
    -
    -    optional<rect> m_clipping_rect ;
    -
    -};
    -
    -

    Bypassing expensive unnecesary default construction

    -
    class ExpensiveCtor { ... } ;
    -class Fred
    -{
    -  Fred() : mLargeVector(10000) {}
    -
    -  std::vector< optional<ExpensiveCtor> > mLargeVector ;
    -} ;
    -
    - -
    - -

    Optional references

    -

    This library allow the template parameter T to be of reference type: T&, and -to some extent, T const&.

    - -

    However, since references are not real objects some restrictions apply and -some operations are not available in this case:

    - - -

    Also, even though optional<T&> treats it wrapped pseudo-object much as a real -value, a true real reference is stored so aliasing will ocurr:

    - - - -
    - -

    In-Place Factories

    -

    -One of the typical problems with wrappers and containers is that their -interfaces usually provide an operation to initialize or assign the contained -object as a copy of some other object. This not only requires the underlying -type to be Copy Constructible, but also requires the existence of a fully -constructed object, often temporary, just to follow the copy from:

    -
    struct X 
    -{
    -  X ( int, std:::string ) ; 
    -} ;
    -
    class W
    -{
    -  X wrapped_ ;
    -  
    -public:
    -
    -  W ( X const& x ) : wrapped_(x) {}  
    -} ;
    -
    void foo()
    -{
    -  // Temporary object created.
    -  W ( 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 shceme, the user only needs to supply the arguments to the constructor -to use in the wrapped object construction.

    -
    class W
    -{
    -  X wrapped_ ;
    -  
    -public:
    -
    -  W ( X const& x ) : wrapped_(x) {}  
    -  W ( int a0, std::string a1) : wrapped_(a0,a1) {}
    -} ;
    -
    void foo()
    -{
    -  // Wrapped object constructed in-place
    -  // No temporary created.
    -  W (123,"hello") ; 
    -}
    -
    -

    A limitation of this method is that it doesn't scale well to wrapped objects with multiple -constructors nor to generic code were the constructor overloads are unknown.

    -

    The solution presented in this library is the familiy of InPlaceFactories and -TypedInPlaceFactories.
    -These factories are a family of classes which encapsulate an increasing number of arbitrary -constructor parameters and supply a method to construct an object of a given type using those -parameters at an address specified by the user via placement new.

    -

     For example, one member of this familiy looks like:

    -
    template<class T,class A0, class A1>
    -class TypedInPlaceFactory2
    -{
    -  A0 m_a0 ; A1 m_a1 ;
    -  
    -public:
    -
    -  TypedInPlaceFactory2( A0 const& a0, A1 const& a1 ) : m_a0(a0), m_a1(a1) {}
    -
    -  void construct ( void* p ) { new (p) T(m_a0,m_a1) ; }  
    -} ;
    -
    -

    A wrapper class aware of this can use it as:

    -
    class W
    -{
    -  X wrapped_ ;
    -  
    -public:
    -
    -  W ( X const& x ) : wrapped_(x) {}  
    -  W ( TypedInPlaceFactory2 const& fac ) { fac.construct(&wrapped_) ; }
    -} ;
    -
    void foo()
    -{
    -  // Wrapped object constructed in-place via a TypedInPlaceFactory.
    -  // No temporary created.
    -  W ( TypedInPlaceFactory2<X,int,std::string&rt;(123,"hello")) ; 
    -}
    -
    -

    The factories are divided in two groups:

    -

    Within each group, all the family members differ only in the number of parameters allowed.

    -

    -

    This library provides an overloaded set of helper template functions to construct these factories -without requiring unnecessary template parameters:

    -
    template<class A0,...,class AN> 
    -InPlaceFactoryN <A0,...,AN> in_place ( A0 const& a0, ..., AN const& aN) ;
    -
    -template<class T,class A0,...,class AN> 
    -TypedInPlaceFactoryN <T,A0,...,AN> in_place ( T const& a0, A0 const& a0, ..., AN const& aN) ;
    - -

    In-place factories can be used generically by the wrapper and user as follows:

    -
    class W
    -{
    -  X wrapped_ ;
    -  
    -public:
    -
    -  W ( X const& x ) : wrapped_(x) {}  
    -  
    -  template
    -  W ( InPlaceFactory const& fac ) { fac.template <X>construct(&wrapped_) ; }
    -  
    -} ;
    -
    void foo()
    -{
    -  // Wrapped object constructed in-place via a InPlaceFactory.
    -  // No temporary created.
    -  W ( in_place(123,"hello") ) ; 
    -}
    -
    -

    The factories are implemented in the headers: -in_place_factory.hpp and -typed_in_place_factory.hpp -

    - -
    - -

    A note about optional<bool>

    -

    optional<bool> should be used with special caution and consideration.

    -

    First, it is functionally similar to a tristate boolean (false,maybe,true) —such as boost::tribool (not yet formally in boost)—except that in a tristate boolean, -the maybe state represents a valid value, unlike the corresponding state -of an uninitialized optional<bool>.
    -It should be carefully considered if an optional bool instead of a tribool is really needed

    -

    Second, optional<> provides an implicit conversion to bool. This conversion - refers to the initialization state and not to the contained value.
    -Using optional<bool> can lead to subtle errors due to the implicit bool conversion:

    -
    void foo ( bool v ) ;
    -void bar()
    -{
    -  optional<bool> v = try();
    -
    -  // The following intended to pass the value of 'v' to foo():
    -  foo(v);
    -  // But instead, the initialization state is passed
    -  // due to a typo: it should have been foo(*v).
    -}
    -
    -

    The only implicit conversion is to bool, and it is safe in the sense that typical -integral promotions don't apply (i.e. if foo() takes an 'int' instead, it won't compile).


    - -

    Exception Safety Guarantees

    -

    Assignment and Reset:

    -

    Because of the current implementation (see Implementation Notes), all -of the assignment methods:

    - -

    Can only guarantee the basic exception safety: The lvalue optional is left uninitialized -if an exception is thrown (any previous value is first destroyed using T::~T())

    -

    On the other hand, the uninitializing methods:

    - -

    Provide the no-throw guarantee (assuming a no-throw T::~T())

    -

    However, since optional<> itself doesn't throw any exceptions, -the only source for exceptions here are T's constructor, so if you know the exception guarantees -for T::T ( T const& ), you know that optional's assignment and reset has the same guarantees.

    -
    //
    -// Case 1: Exception thrown during assignment.
    -//
    -T v0(123);
    -optional<T> opt0(v0);
    -try
    -{
    -  T v1(456);
    -  optional<T> opt1(v1);
    -  opt0 = opt1 ;
    -
    -  // If no exception was thrown, assignment succeeded.
    -  assert( *opt0 == v1 ) ;
    -}
    -catch(...)
    -{
    -  // If any exception was thrown, 'opt0' is reset to uninitialized.
    -  assert( !opt0 ) ;
    -}
    -
    -//
    -// Case 2: Exception thrown during reset(v)
    -//
    -T v0(123);
    -optional<T> opt(v0);
    -try
    -{
    -  T v1(456);
    -  opt.reset ( v1 ) ;
    -
    -  // If no exception was thrown, reset succeeded.
    -  assert( *opt == v1 ) ;
    -}
    -catch(...)
    -{
    -  // If any exception was thrown, 'opt' is reset to uninitialized.
    -  assert( !opt ) ;
    -}
    -
    -

    Swap:

    -

    void swap( optional<T>&, optional<T>& ) has the same exception guarantee as swap(T&,T&) when both optionals are initialized.
    -If only one of the optionals is initialized, it gives the same basic exception guarantee as optional<T>::reset( T const& ) (since optional<T>::reset() doesn't throw).
    -If none of the optionals is initialized, it has no-throw guarantee since it is a no-op.

    - -
    - -

    Type requirements

    -

    In general, T must be Copy Constructible and have a no-throw destructor. The copy-constructible requirement is not needed -if InPlaceFactories are used.
    -T is not required to be Default Constructible

    - -
    - -

    Implementation Notes

    -

    optional<T> is currently implemented - using a custom aligned storage facility built from alignment_of and type_with_alignment (both from Type Traits). - It uses a separate boolean flag to indicate the initialization state.
    - Placement new with T's copy constructor and T's destructor - are explicitly used to initialize,copy and destroy optional values.
    - As a result, T's default constructor is effectively by-passed, but the exception - guarantees are basic.
    - It is planned to replace the current implementation with another with - stronger exception safety, such as a future boost::variant.

    - -
    - -

    Dependencies and Portability

    - -

    The implementation uses type_traits/alignment_of.hpp and type_traits/type_with_alignment.hpp

    - -
    - -

    Acknowledgments

    -

    Pre-formal review:

    -
    -

    Peter Dimov suggested the name 'optional', and was the first to point out the - need for aligned storage
    - Douglas Gregor developed 'type_with_alignment', and later Eric Friedman coded - 'aligned_storage', which are the core of the optional class implementation.
    - Andrei Alexandrescu and Brian Parker also worked with aligned storage techniques - and their work influenced the current implementation.
    - Gennadiy Rozental made extensive and important comments which shaped the design.
    - Vesa Karvonen and Douglas Gregor made quite useful comparisons between optional, - variant and any; and made other relevant comments. Douglas Gregor and Peter - Dimov commented on comparisons and evaluation in boolean contexts.
    - Eric Friedman helped understand the issues involved with aligned storage, move/copy - operations and exception safety.
    - Many others have participated with useful comments: Aleksey Gurotov, Kevlin - Henney, David Abrahams, and others I can't recall.

    -
    -

    Post-formal review:

    -
    -

    William Kempf carefully considered the originally proposed interface and - suggested the new interface which is currently used. He also started and fueled - the discussion about the analogy optional<>/smart pointer and about - relational operators.
    - Peter Dimov, Joel de Guzman, David Abrahams, Tanton Gibbs and Ian Hanson focused - on the relational semantics of optional (originally undefined); concluding - with the fact that the pointer-like interface doesn't make it a pointer so - it shall have deep relational operators.
    - Augustus Saunders also explored the different relational semantics between - optional<> and a pointer and developed the OptionalPointee concept as - an aid against potential conflicts on generic code.
    - Joel de Guzman noticed that optional<> can be seen as an API on top - of variant<T,nil_t>.
    - Dave Gomboc explained the meaning and usage of the Haskell analog to optional<>: - the Maybe type constructor (analogy originally pointed out by David Sankel).
    - Other comments were posted by Vincent Finn, Anthony Williams, Ed Brey, Rob - Stewart, and others.
    - Joel de Guzman made the case for the support of references and helped with - the proper semantics.
    - Mat Marcus shown the virtues of a value-oriented interface, influencing the - current design, and contributed the idea of "none".

    -
    -
    - -

    Revised Jannuary 30, 2004

    -

    © Copyright boost.org 2003. Permission to copy, use, modify, sell and - distribute this document is granted provided this copyright notice appears in - all copies. This document is provided "as is" without express or implied - warranty, and with no claim as to its suitability for any purpose.

    -

    Developed by Fernando Cacciola, -the latest version of this file can be found at www.boost.org, and the boost -discussion lists

    - - diff --git a/index.html b/index.html deleted file mode 100644 index cac816c..0000000 --- a/index.html +++ /dev/null @@ -1,9 +0,0 @@ - - - - - -Automatic redirection failed, please go to -doc/optional.html. - - \ No newline at end of file diff --git a/test/.cvsignore b/test/.cvsignore deleted file mode 100644 index ba077a4..0000000 --- a/test/.cvsignore +++ /dev/null @@ -1 +0,0 @@ -bin diff --git a/test/Jamfile b/test/Jamfile deleted file mode 100644 index 841647d..0000000 --- a/test/Jamfile +++ /dev/null @@ -1,36 +0,0 @@ -# Boost.Optional Library test Jamfile -# -# Copyright (C) 2003, Fernando Luis Cacciola Carballal. -# -# Use, modification, and distribution is 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) -# - -subproject libs/optional/test ; - -# bring in rules for testing -SEARCH on testing.jam = $(BOOST_BUILD_PATH) ; -include testing.jam ; - -# Make tests run by default. -DEPENDS all : test ; - -{ - test-suite optional : - [ run optional_test.cpp ] - [ run optional_test_tie.cpp ] - [ run optional_test_ref.cpp ] - [ run optional_test_inplace.cpp ] - [ compile-fail optional_test_fail1.cpp ] - [ compile-fail optional_test_fail2.cpp ] - [ compile-fail optional_test_fail3a.cpp ] - [ compile-fail optional_test_fail3b.cpp ] - [ compile-fail optional_test_ref_fail1.cpp ] - [ compile-fail optional_test_ref_fail2.cpp ] - [ compile-fail optional_test_ref_fail3.cpp ] - [ compile-fail optional_test_ref_fail4.cpp ] - [ compile-fail optional_test_inplace_fail.cpp ] - [ compile-fail optional_test_inplace_fail2.cpp ] - ; -} diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 deleted file mode 100644 index 413d65b..0000000 --- a/test/Jamfile.v2 +++ /dev/null @@ -1,34 +0,0 @@ -# Boost.Optional Library test Jamfile -# -# Copyright (C) 2003, Fernando Luis Cacciola Carballal. -# -# This material is provided "as is", with absolutely no warranty expressed -# or implied. Any use is at your own risk. -# -# Permission to use or copy this software for any purpose is hereby granted -# without fee, provided the above notices are retained on all copies. -# Permission to modify the code and to distribute modified code is granted, -# provided the above notices are retained, and a notice that the code was -# modified is included with the above copyright notice. -# - -import testing ; - -{ - test-suite optional : - [ run optional_test.cpp ] - [ run optional_test_tie.cpp ] - [ run optional_test_ref.cpp ] - [ run optional_test_inplace.cpp ] - [ compile-fail optional_test_fail1.cpp ] - [ compile-fail optional_test_fail2.cpp ] - [ compile-fail optional_test_fail3a.cpp ] - [ compile-fail optional_test_fail3b.cpp ] - [ compile-fail optional_test_ref_fail1.cpp ] - [ compile-fail optional_test_ref_fail2.cpp ] - [ compile-fail optional_test_ref_fail3.cpp ] - [ compile-fail optional_test_ref_fail4.cpp ] - [ compile-fail optional_test_inplace_fail.cpp ] - [ compile-fail optional_test_inplace_fail2.cpp ] - ; -} diff --git a/test/optional_test.cpp b/test/optional_test.cpp deleted file mode 100644 index d42f733..0000000 --- a/test/optional_test.cpp +++ /dev/null @@ -1,801 +0,0 @@ -// Copyright (C) 2003, Fernando Luis Cacciola Carballal. -// -// Use, modification, and distribution is 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) -// -// See http://www.boost.org/lib/optional for documentation. -// -// You are welcome to contact the author at: -// fernando_cacciola@hotmail.com -// -#include -#include -#include - -#define BOOST_ENABLE_ASSERT_HANDLER - -#include "boost/optional.hpp" - -#ifdef __BORLANDC__ -#pragma hdrstop -#endif - -#include "boost/none.hpp" - -#include "boost/test/minimal.hpp" - -#include "optional_test_common.cpp" - -void test_implicit_construction ( optional opt, double v, double z ) -{ - check_value(opt,v,z); -} - -void test_implicit_construction ( optional opt, X const& v, X const& z ) -{ - check_value(opt,v,z); -} - -void test_default_implicit_construction ( double, optional opt ) -{ - BOOST_CHECK(!opt); -} - -void test_default_implicit_construction ( X const&, optional opt ) -{ - BOOST_CHECK(!opt); -} - -// -// Basic test. -// Check ordinary functionality: -// Initialization, assignment, comparison and value-accessing. -// -template -void test_basics( T const* ) -{ - TRACE( std::endl << BOOST_CURRENT_FUNCTION ); - - T z(0); - - T a(1); - - // Default construction. - // 'def' state is Uninitialized. - // T::T() is not called (and it is not even defined) - optional def ; - check_uninitialized(def); - - // Implicit construction - // The first parameter is implicitely converted to optional(a); - test_implicit_construction(a,a,z); - - // Direct initialization. - // 'oa' state is Initialized with 'a' - // T::T( T const& x ) is used. - set_pending_copy( ARG(T) ) ; - optional oa ( a ) ; - check_is_not_pending_copy( ARG(T) ); - check_initialized(oa); - check_value(oa,a,z); - - T b(2); - - optional ob ; - - // Value-Assignment upon Uninitialized optional. - // T::T ( T const& x ) is used. - set_pending_copy( ARG(T) ) ; - ob = a ; - check_is_not_pending_copy( ARG(T) ) ; - check_initialized(ob); - check_value(ob,a,z); - - // Value-Assignment upon Initialized optional. - // T::T ( T const& x ) is used - set_pending_dtor( ARG(T) ) ; - set_pending_copy( ARG(T) ) ; - ob = b ; - check_is_not_pending_dtor( ARG(T) ) ; - check_is_not_pending_copy( ARG(T) ) ; - check_initialized(ob); - check_value(ob,b,z); - - // Assignment initialization. - // T::T ( T const& x ) is used to copy new value. - set_pending_copy( ARG(T) ) ; - optional const oa2 ( oa ) ; - check_is_not_pending_copy( ARG(T) ) ; - check_initialized_const(oa2); - check_value_const(oa2,a,z); - - // Assignment - // T::~T() is used to destroy previous value in ob. - // T::T ( T const& x ) is used to copy new value. - set_pending_dtor( ARG(T) ) ; - set_pending_copy( ARG(T) ) ; - oa = ob ; - check_is_not_pending_dtor( ARG(T) ) ; - check_is_not_pending_copy( ARG(T) ) ; - check_initialized(oa); - check_value(oa,b,z); - - // Uninitializing Assignment upon Initialized Optional - // T::~T() is used to destroy previous value in oa. - set_pending_dtor( ARG(T) ) ; - set_pending_copy( ARG(T) ) ; - oa = def ; - check_is_not_pending_dtor( ARG(T) ) ; - check_is_pending_copy ( ARG(T) ) ; - check_uninitialized(oa); - - // Uninitializing Assignment upon Uninitialized Optional - // (Dtor is not called this time) - set_pending_dtor( ARG(T) ) ; - set_pending_copy( ARG(T) ) ; - oa = def ; - check_is_pending_dtor( ARG(T) ) ; - check_is_pending_copy( ARG(T) ) ; - check_uninitialized(oa); - - // Deinitialization of Initialized Optional - // T::~T() is used to destroy previous value in ob. - set_pending_dtor( ARG(T) ) ; - ob.reset(); - check_is_not_pending_dtor( ARG(T) ) ; - check_uninitialized(ob); - - // Deinitialization of Uninitialized Optional - // (Dtor is not called this time) - set_pending_dtor( ARG(T) ) ; - ob.reset(); - check_is_pending_dtor( ARG(T) ) ; - check_uninitialized(ob); -} - -// -// Test Direct Value Manipulation -// -template -void test_direct_value_manip( T const* ) -{ - TRACE( std::endl << BOOST_CURRENT_FUNCTION ); - - T x(3); - - optional const c_opt0(x) ; - optional opt0(x); - - BOOST_CHECK( c_opt0.get().V() == x.V() ) ; - BOOST_CHECK( opt0.get().V() == x.V() ) ; - - BOOST_CHECK( c_opt0->V() == x.V() ) ; - BOOST_CHECK( opt0->V() == x.V() ) ; - - BOOST_CHECK( (*c_opt0).V() == x.V() ) ; - BOOST_CHECK( (* opt0).V() == x.V() ) ; - - T y(4); - opt0 = y ; - BOOST_CHECK( get(opt0).V() == y.V() ) ; -} - -// -// Test Uninitialized access assert -// -template -void test_uninitialized_access( T const* ) -{ - TRACE( std::endl << BOOST_CURRENT_FUNCTION ); - - optional def ; - - bool passed = false ; - try - { - // This should throw because 'def' is uninitialized - T const& n = def.get() ; - unused_variable(n); - passed = true ; - } - catch (...) {} - BOOST_CHECK(!passed); - - passed = false ; - try - { - // This should throw because 'def' is uninitialized - T const& n = *def ; - unused_variable(n); - passed = true ; - } - catch (...) {} - BOOST_CHECK(!passed); - - passed = false ; - try - { - T v(5) ; - unused_variable(v); - // This should throw because 'def' is uninitialized - *def = v ; - passed = true ; - } - catch (...) {} - BOOST_CHECK(!passed); - - passed = false ; - try - { - // This should throw because 'def' is uninitialized - T v = *(def.operator->()) ; - unused_variable(v); - passed = true ; - } - catch (...) {} - BOOST_CHECK(!passed); -} - -#if BOOST_WORKAROUND( BOOST_INTEL_CXX_VERSION, <= 700) // Intel C++ 7.0 -void prevent_buggy_optimization( bool v ) {} -#endif - -// -// Test Direct Initialization of optional for a T with throwing copy-ctor. -// -template -void test_throwing_direct_init( T const* ) -{ - TRACE( std::endl << BOOST_CURRENT_FUNCTION ); - - T a(6); - - int count = get_instance_count( ARG(T) ) ; - - set_throw_on_copy( ARG(T) ) ; - - bool passed = false ; - try - { - // This should: - // Attempt to copy construct 'a' and throw. - // 'opt' won't be constructed. - set_pending_copy( ARG(T) ) ; - -#if BOOST_WORKAROUND( BOOST_INTEL_CXX_VERSION, <= 700) // Intel C++ 7.0 - // Intel C++ 7.0 specific: - // For some reason, when "check_is_not_pending_copy", - // after the exception block is reached, - // X::pending_copy==true even though X's copy ctor set it to false. - // I guessed there is some sort of optimization bug, - // and it seems to be the since the following additional line just - // solves the problem (!?) - prevent_buggy_optimization(X::pending_copy); -#endif - - optional opt(a) ; - passed = true ; - } - catch ( ... ){} - - BOOST_CHECK(!passed); - check_is_not_pending_copy( ARG(T) ); - check_instance_count(count, ARG(T) ); -} - -// -// Test Value Assignment to an Uninitialized optional for a T with a throwing copy-ctor -// -template -void test_throwing_val_assign_on_uninitialized( T const* ) -{ - TRACE( std::endl << BOOST_CURRENT_FUNCTION ); - - T a(7); - - int count = get_instance_count( ARG(T) ) ; - - set_throw_on_copy( ARG(T) ) ; - - optional opt ; - - bool passed = false ; - try - { - // This should: - // Attempt to copy construct 'a' and throw. - // opt should be left uninitialized. - set_pending_copy( ARG(T) ) ; - opt.reset( a ); - passed = true ; - } - catch ( ... ) {} - - BOOST_CHECK(!passed); - - check_is_not_pending_copy( ARG(T) ); - check_instance_count(count, ARG(T) ); - check_uninitialized(opt); -} - -// -// Test Value Reset on an Initialized optional for a T with a throwing copy-ctor -// -template -void test_throwing_val_assign_on_initialized( T const* ) -{ - TRACE( std::endl << BOOST_CURRENT_FUNCTION ); - - T z(0); - T a(8); - T b(9); - - int count = get_instance_count( ARG(T) ) ; - - reset_throw_on_copy( ARG(T) ) ; - - optional opt ( b ) ; - ++ count ; - - check_instance_count(count, ARG(T) ); - - check_value(opt,b,z); - - set_throw_on_copy( ARG(T) ) ; - - bool passed = false ; - try - { - // This should: - // Attempt to copy construct 'a' and throw. - // opt should be left uninitialized (even though it was initialized) - set_pending_dtor( ARG(T) ) ; - set_pending_copy( ARG(T) ) ; - opt.reset ( a ) ; - passed = true ; - } - catch ( ... ) {} - - BOOST_CHECK(!passed); - - -- count ; - - check_is_not_pending_dtor( ARG(T) ); - check_is_not_pending_copy( ARG(T) ); - check_instance_count(count, ARG(T) ); - check_uninitialized(opt); -} - -// -// Test Copy Initialization from an Initialized optional for a T with a throwing copy-ctor -// -template -void test_throwing_copy_initialization( T const* ) -{ - TRACE( std::endl << BOOST_CURRENT_FUNCTION ); - - T z(0); - T a(10); - - reset_throw_on_copy( ARG(T) ) ; - - optional opt (a); - - int count = get_instance_count( ARG(T) ) ; - - set_throw_on_copy( ARG(T) ) ; - - bool passed = false ; - try - { - // This should: - // Attempt to copy construct 'opt' and throw. - // opt1 won't be constructed. - set_pending_copy( ARG(T) ) ; - optional opt1 = opt ; - passed = true ; - } - catch ( ... ) {} - - BOOST_CHECK(!passed); - - check_is_not_pending_copy( ARG(T) ); - check_instance_count(count, ARG(T) ); - - // Nothing should have happened to the source optional. - check_initialized(opt); - check_value(opt,a,z); -} - -// -// Test Assignment to an Uninitialized optional from an Initialized optional -// for a T with a throwing copy-ctor -// -template -void test_throwing_assign_to_uninitialized( T const* ) -{ - TRACE( std::endl << BOOST_CURRENT_FUNCTION ); - - T z(0); - T a(11); - - reset_throw_on_copy( ARG(T) ) ; - - optional opt0 ; - optional opt1(a) ; - - int count = get_instance_count( ARG(T) ) ; - - set_throw_on_copy( ARG(T) ) ; - - bool passed = false ; - try - { - // This should: - // Attempt to copy construct 'opt1.value()' into opt0 and throw. - // opt0 should be left uninitialized. - set_pending_copy( ARG(T) ) ; - opt0 = opt1 ; - passed = true ; - } - catch ( ... ) {} - - BOOST_CHECK(!passed); - - check_is_not_pending_copy( ARG(T) ); - check_instance_count(count, ARG(T) ); - check_uninitialized(opt0); -} - -// -// Test Assignment to an Initialized optional from an Initialized optional -// for a T with a throwing copy-ctor -// -template -void test_throwing_assign_to_initialized( T const* ) -{ - TRACE( std::endl << BOOST_CURRENT_FUNCTION ); - - T z(0); - T a(12); - T b(13); - - reset_throw_on_copy( ARG(T) ) ; - - optional opt0(a) ; - optional opt1(b) ; - - int count = get_instance_count( ARG(T) ) ; - - set_throw_on_copy( ARG(T) ) ; - - bool passed = false ; - try - { - // This should: - // Attempt to copy construct 'opt1.value()' into opt0 and throw. - // opt0 should be left unmodified or uninitialized - set_pending_dtor( ARG(T) ) ; - set_pending_copy( ARG(T) ) ; - opt0 = opt1 ; - passed = true ; - } - catch ( ... ) {} - - BOOST_CHECK(!passed); - - // opt0 was left uninitialized - -- count ; - check_is_not_pending_dtor( ARG(T) ); - check_is_not_pending_copy( ARG(T) ); - check_instance_count(count, ARG(T) ); - check_uninitialized(opt0); -} - -// -// Test swap in a no-throwing case -// -template -void test_no_throwing_swap( T const* ) -{ - TRACE( std::endl << BOOST_CURRENT_FUNCTION ); - - T z(0); - T a(14); - T b(15); - - reset_throw_on_copy( ARG(T) ) ; - - optional def0 ; - optional def1 ; - optional opt0(a) ; - optional opt1(b) ; - - int count = get_instance_count( ARG(T) ) ; - - swap(def0,def1); - check_uninitialized(def0); - check_uninitialized(def1); - - swap(def0,opt0); - check_uninitialized(opt0); - check_initialized(def0); - check_value(def0,a,z); - - // restore def0 and opt0 - swap(def0,opt0); - - swap(opt0,opt1); - check_instance_count(count, ARG(T) ); - check_initialized(opt0); - check_initialized(opt1); - check_value(opt0,b,z); - check_value(opt1,a,z); -} - -// -// Test swap in a throwing case -// -template -void test_throwing_swap( T const* ) -{ - TRACE( std::endl << BOOST_CURRENT_FUNCTION ); - - T a(16); - T b(17); - - reset_throw_on_copy( ARG(T) ) ; - - optional opt0(a) ; - optional opt1(b) ; - - set_throw_on_copy( ARG(T) ) ; - - // - // Case 1: Both Initialized. - // - bool passed = false ; - try - { - // This should attempt to swap optionals and fail at swap(X&,X&). - swap(opt0,opt1); - - passed = true ; - } - catch ( ... ) {} - - BOOST_CHECK(!passed); - - // Assuming swap(T&,T&) has at least the basic guarantee, these should hold. - BOOST_CHECK( ( !opt0 || ( !!opt0 && ( ( *opt0 == a ) || ( *opt0 == b ) ) ) ) ) ; - BOOST_CHECK( ( !opt1 || ( !!opt1 && ( ( *opt1 == a ) || ( *opt1 == b ) ) ) ) ) ; - - // - // Case 2: Only one Initialized. - // - reset_throw_on_copy( ARG(T) ) ; - - opt0.reset(); - opt1.reset(a); - - set_throw_on_copy( ARG(T) ) ; - - passed = false ; - try - { - // This should attempt to swap optionals and fail at opt0.reset(*opt1) - // opt0 should be left uninitialized and opt1 unchanged. - swap(opt0,opt1); - - passed = true ; - } - catch ( ... ) {} - - BOOST_CHECK(!passed); - - check_uninitialized(opt0); - check_initialized(opt1); - check_value(opt1,a,b); -} - -// -// This verifies relational operators. -// -template -void test_relops( T const* ) -{ - TRACE( std::endl << BOOST_CURRENT_FUNCTION ); - - reset_throw_on_copy( ARG(T) ) ; - - T v0(18); - T v1(19); - T v2(19); - - optional def0 ; - optional def1 ; - optional opt0(v0); - optional opt1(v1); - optional opt2(v2); - - // Check identity - BOOST_CHECK ( def0 == def0 ) ; - BOOST_CHECK ( opt0 == opt0 ) ; - BOOST_CHECK ( !(def0 != def0) ) ; - BOOST_CHECK ( !(opt0 != opt0) ) ; - - // Check when both are uininitalized. - BOOST_CHECK ( def0 == def1 ) ; // both uninitialized compare equal - BOOST_CHECK ( !(def0 < def1) ) ; // uninitialized is never less than uninitialized - BOOST_CHECK ( !(def0 > def1) ) ; // uninitialized is never greater than uninitialized - BOOST_CHECK ( !(def0 != def1) ) ; - BOOST_CHECK ( def0 <= def1 ) ; - BOOST_CHECK ( def0 >= def1 ) ; - - // Check when only lhs is uninitialized. - BOOST_CHECK ( def0 != opt0 ) ; // uninitialized is never equal to initialized - BOOST_CHECK ( !(def0 == opt0) ) ; - BOOST_CHECK ( def0 < opt0 ) ; // uninitialized is always less than initialized - BOOST_CHECK ( !(def0 > opt0) ) ; - BOOST_CHECK ( def0 <= opt0 ) ; - BOOST_CHECK ( !(def0 >= opt0) ) ; - - // Check when only rhs is uninitialized. - BOOST_CHECK ( opt0 != def0 ) ; // initialized is never equal to uninitialized - BOOST_CHECK ( !(opt0 == def0) ) ; - BOOST_CHECK ( !(opt0 < def0) ) ; // initialized is never less than uninitialized - BOOST_CHECK ( opt0 > def0 ) ; - BOOST_CHECK ( !(opt0 <= def0) ) ; - BOOST_CHECK ( opt0 >= opt0 ) ; - - // If both are initialized, values are compared - BOOST_CHECK ( opt0 != opt1 ) ; - BOOST_CHECK ( opt1 == opt2 ) ; - BOOST_CHECK ( opt0 < opt1 ) ; - BOOST_CHECK ( opt1 > opt0 ) ; - BOOST_CHECK ( opt1 <= opt2 ) ; - BOOST_CHECK ( opt1 >= opt0 ) ; -} - -template -void test_none( T const* ) -{ - TRACE( std::endl << BOOST_CURRENT_FUNCTION ); - - using boost::none ; - - optional def0 ; - optional def1(none) ; - optional non_def( T(1234) ) ; - - BOOST_CHECK ( def0 == none ) ; - BOOST_CHECK ( non_def != none ) ; - BOOST_CHECK ( !def1 ) ; - - non_def = none ; - BOOST_CHECK ( !non_def ) ; - - test_default_implicit_construction(T(1),none); -} - -void test_with_builtin_types() -{ - TRACE( std::endl << BOOST_CURRENT_FUNCTION ); - - test_basics( ARG(double) ); - test_uninitialized_access( ARG(double) ); - test_no_throwing_swap( ARG(double) ); - test_relops( ARG(double) ) ; - test_none( ARG(double) ) ; -} - -void test_with_class_type() -{ - TRACE( std::endl << BOOST_CURRENT_FUNCTION ); - - test_basics( ARG(X) ); - test_direct_value_manip( ARG(X) ); - test_uninitialized_access( ARG(X) ); - test_throwing_direct_init( ARG(X) ); - test_throwing_val_assign_on_uninitialized( ARG(X) ); - test_throwing_val_assign_on_initialized( ARG(X) ); - test_throwing_copy_initialization( ARG(X) ); - test_throwing_assign_to_uninitialized( ARG(X) ); - test_throwing_assign_to_initialized( ARG(X) ); - test_no_throwing_swap( ARG(X) ); - test_throwing_swap( ARG(X) ); - test_relops( ARG(X) ) ; - test_none( ARG(X) ) ; - BOOST_CHECK ( X::count == 0 ) ; -} - -int eat ( bool ) { return 1 ; } -int eat ( char ) { return 1 ; } -int eat ( int ) { return 1 ; } -int eat ( void const* ) { return 1 ; } - -template int eat ( T ) { return 0 ; } - -// -// This verifies that operator safe_bool() behaves properly. -// -template -void test_no_implicit_conversions_impl( T const& ) -{ - TRACE( std::endl << BOOST_CURRENT_FUNCTION ); - - optional def ; - BOOST_CHECK ( eat(def) == 0 ) ; -} - -void test_no_implicit_conversions() -{ - TRACE( std::endl << BOOST_CURRENT_FUNCTION ); - - bool b = false ; - char c = 0 ; - int i = 0 ; - void const* p = 0 ; - - test_no_implicit_conversions_impl(b); - test_no_implicit_conversions_impl(c); - test_no_implicit_conversions_impl(i); - test_no_implicit_conversions_impl(p); -} - -struct A {} ; -void test_conversions1() -{ - TRACE( std::endl << BOOST_CURRENT_FUNCTION ); - -#ifndef BOOST_OPTIONAL_NO_CONVERTING_COPY_CTOR - char c = 20 ; - optional opt0(c); - optional opt1(opt0); - BOOST_CHECK(*opt1 == static_cast(c)); -#endif - -#ifndef BOOST_OPTIONAL_NO_CONVERTING_ASSIGNMENT - float f = 21.22f ; - double d = f ; - optional opt2(f) ; - optional opt3 ; - opt3 = opt2 ; - BOOST_CHECK(*opt3 == d); -#endif -} - -void test_conversions2() -{ - TRACE( std::endl << BOOST_CURRENT_FUNCTION ); - - char c = 20 ; - optional opt(c); - BOOST_CHECK( get(opt) == static_cast(c)); - - float f = 21.22f ; - optional opt1; - opt1 = f ; - BOOST_CHECK(*get(&opt1) == static_cast(f)); -} - -int test_main( int, char* [] ) -{ - try - { - test_with_class_type(); - test_with_builtin_types(); - test_no_implicit_conversions(); - test_conversions1(); - test_conversions2(); - } - catch ( ... ) - { - BOOST_ERROR("Unexpected Exception caught!"); - } - - return 0; -} - - diff --git a/test/optional_test_common.cpp b/test/optional_test_common.cpp deleted file mode 100644 index fffe6fd..0000000 --- a/test/optional_test_common.cpp +++ /dev/null @@ -1,241 +0,0 @@ -// Copyright (C) 2003, Fernando Luis Cacciola Carballal. -// -// Use, modification, and distribution is 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) -// -// See http://www.boost.org/lib/optional for documentation. -// -// You are welcome to contact the author at: -// fernando_cacciola@hotmail.com -// -#ifdef ENABLE_TRACE -#define TRACE(msg) std::cout << msg << std::endl ; -#else -#define TRACE(msg) -#endif - -namespace boost { - -void assertion_failed (char const * expr, char const * func, char const * file, long ) -{ - using std::string ; - string msg = string("Boost assertion failure for \"") - + string(expr) - + string("\" at file \"") - + string(file) - + string("\" function \"") - + string(func) - + string("\"") ; - - TRACE(msg); - - throw std::logic_error(msg); -} - -} - -using boost::optional ; - -template inline void unused_variable ( T ) {} - -#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP -using boost::swap ; -using boost::get ; -using boost::get_pointer ; -#endif - -// MSVC6.0 does not support comparisons of optional against a literal null pointer value (0) -// via the safe_bool operator. -#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1300) ) // 1300 == VC++ 7.1 -#define BOOST_OPTIONAL_NO_NULL_COMPARE -#endif - -#define ARG(T) (static_cast< T const* >(0)) - -// -// Helper class used to verify the lifetime managment of the values held by optional -// -class X -{ - public : - - X ( int av ) : v(av) - { - ++ count ; - - TRACE ( "X::X(" << av << "). this=" << this ) ; - } - - X ( X const& rhs ) : v(rhs.v) - { - pending_copy = false ; - - TRACE ( "X::X( X const& rhs). this=" << this << " rhs.v=" << rhs.v ) ; - - if ( throw_on_copy ) - { - TRACE ( "throwing exception in X's copy ctor" ) ; - throw 0 ; - } - - ++ count ; - } - - ~X() - { - pending_dtor = false ; - - -- count ; - - TRACE ( "X::~X(). v=" << v << " this=" << this ); - } - - X& operator= ( X const& rhs ) - { - v = rhs.v ; - - TRACE ( "X::operator =( X const& rhs). this=" << this << " rhs.v=" << rhs.v ) ; - - return *this ; - } - - friend bool operator == ( X const& a, X const& b ) - { return a.v == b.v ; } - - friend bool operator != ( X const& a, X const& b ) - { return a.v != b.v ; } - - friend bool operator < ( X const& a, X const& b ) - { return a.v < b.v ; } - - int V() const { return v ; } - int& V() { return v ; } - - static int count ; - static bool pending_copy ; - static bool pending_dtor ; - static bool throw_on_copy ; - - private : - - int v ; - - private : - - X() ; -} ; - - -int X::count = 0 ; -bool X::pending_copy = false ; -bool X::pending_dtor = false ; -bool X::throw_on_copy = false ; - -inline void set_pending_copy ( X const* x ) { X::pending_copy = true ; } -inline void set_pending_dtor ( X const* x ) { X::pending_dtor = true ; } -inline void set_throw_on_copy ( X const* x ) { X::throw_on_copy = true ; } -inline void reset_throw_on_copy ( X const* x ) { X::throw_on_copy = false ; } -inline void check_is_pending_copy ( X const* x ) { BOOST_CHECK( X::pending_copy ) ; } -inline void check_is_pending_dtor ( X const* x ) { BOOST_CHECK( X::pending_dtor ) ; } -inline void check_is_not_pending_copy( X const* x ) { BOOST_CHECK( !X::pending_copy ) ; } -inline void check_is_not_pending_dtor( X const* x ) { BOOST_CHECK( !X::pending_dtor ) ; } -inline void check_instance_count ( int c, X const* x ) { BOOST_CHECK( X::count == c ) ; } -inline int get_instance_count ( X const* x ) { return X::count ; } - -inline void set_pending_copy (...) {} -inline void set_pending_dtor (...) {} -inline void set_throw_on_copy (...) {} -inline void reset_throw_on_copy (...) {} -inline void check_is_pending_copy (...) {} -inline void check_is_pending_dtor (...) {} -inline void check_is_not_pending_copy(...) {} -inline void check_is_not_pending_dtor(...) {} -inline void check_instance_count (...) {} -inline int get_instance_count (...) { return 0 ; } - - -template -inline void check_uninitialized_const ( optional const& opt ) -{ -#ifndef BOOST_OPTIONAL_NO_NULL_COMPARE - BOOST_CHECK( opt == 0 ) ; -#endif - BOOST_CHECK( !opt ) ; - BOOST_CHECK( !get_pointer(opt) ) ; - BOOST_CHECK( !opt.get_ptr() ) ; -} -template -inline void check_uninitialized ( optional& opt ) -{ -#ifndef BOOST_OPTIONAL_NO_NULL_COMPARE - BOOST_CHECK( opt == 0 ) ; -#endif - BOOST_CHECK( !opt ) ; - BOOST_CHECK( !get_pointer(opt) ) ; - BOOST_CHECK( !opt.get_ptr() ) ; - - check_uninitialized_const(opt); -} - -template -inline void check_initialized_const ( optional const& opt ) -{ - BOOST_CHECK( opt ) ; - -#ifndef BOOST_OPTIONAL_NO_NULL_COMPARE - BOOST_CHECK( opt != 0 ) ; -#endif - - BOOST_CHECK ( !!opt ) ; - BOOST_CHECK ( get_pointer(opt) ) ; - BOOST_CHECK ( opt.get_ptr() ) ; -} - -template -inline void check_initialized ( optional& opt ) -{ - BOOST_CHECK( opt ) ; - -#ifndef BOOST_OPTIONAL_NO_NULL_COMPARE - BOOST_CHECK( opt != 0 ) ; -#endif - - BOOST_CHECK ( !!opt ) ; - BOOST_CHECK ( get_pointer(opt) ) ; - BOOST_CHECK ( opt.get_ptr() ) ; - - check_initialized_const(opt); -} - -template -inline void check_value_const ( optional const& opt, T const& v, T const& z ) -{ - BOOST_CHECK( *opt == v ) ; - BOOST_CHECK( *opt != z ) ; - BOOST_CHECK( opt.get() == v ) ; - BOOST_CHECK( opt.get() != z ) ; - BOOST_CHECK( (*(opt.operator->()) == v) ) ; - BOOST_CHECK( *get_pointer(opt) == v ) ; -} - -template -inline void check_value ( optional& opt, T const& v, T const& z ) -{ -#if BOOST_WORKAROUND(BOOST_MSVC, <= 1200) // 1200 == VC++ 6.0 - // For some reason, VC6.0 is creating a temporary while evaluating (*opt == v), - // so we need to turn throw on copy off first. - reset_throw_on_copy( ARG(T) ) ; -#endif - - BOOST_CHECK( *opt == v ) ; - BOOST_CHECK( *opt != z ) ; - BOOST_CHECK( opt.get() == v ) ; - BOOST_CHECK( opt.get() != z ) ; - BOOST_CHECK( (*(opt.operator->()) == v) ) ; - BOOST_CHECK( *get_pointer(opt) == v ) ; - - check_value_const(opt,v,z); -} - - diff --git a/test/optional_test_fail1.cpp b/test/optional_test_fail1.cpp deleted file mode 100644 index 6073466..0000000 --- a/test/optional_test_fail1.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (C) 2003, Fernando Luis Cacciola Carballal. -// -// Use, modification, and distribution is 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) -// -// See http://www.boost.org/lib/optional for documentation. -// -// You are welcome to contact the author at: -// fernando_cacciola@hotmail.com -// -#include "boost/optional.hpp" - -// -// THIS TEST SHOULD FAIL TO COMPILE -// -void test_deep_constantness() -{ - boost::optional opt ; - boost::optional const copt ; - - *copt = opt ; // Cannot assign to "int const&" -} - - diff --git a/test/optional_test_fail2.cpp b/test/optional_test_fail2.cpp deleted file mode 100644 index 36b42bf..0000000 --- a/test/optional_test_fail2.cpp +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (C) 2003, Fernando Luis Cacciola Carballal. -// -// Use, modification, and distribution is 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) -// -// See http://www.boost.org/lib/optional for documentation. -// -// You are welcome to contact the author at: -// fernando_cacciola@hotmail.com -// -#include "boost/optional.hpp" - -// -// THIS TEST SHOULD FAIL TO COMPILE -// -void test_no_implicit_conversion() -{ - boost::optional opt(1) ; - - // You can compare against 0 or against another optional<>, - // but not against another value - if ( opt == 1 ) ; -} - - diff --git a/test/optional_test_fail3.cpp b/test/optional_test_fail3.cpp deleted file mode 100644 index 1ce685a..0000000 --- a/test/optional_test_fail3.cpp +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (C) 2003, Fernando Luis Cacciola Carballal. -// -// Use, modification, and distribution is 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) -// -// See http://www.boost.org/lib/optional for documentation. -// -// You are welcome to contact the author at: -// fernando_cacciola@hotmail.com -// -#include "boost/optional.hpp" - -// -// THIS TEST SHOULD FAIL TO COMPILE -// -#if BOOST_WORKAROUND( BOOST_INTEL_CXX_VERSION, <= 700) // Intel C++ 7.0 -// Interl C++ 7.0 incorrectly accepts the initialization "boost::optional opt = 3" -// even though the ctor is explicit (c.f. 12.3.1.2), so the test uses another form of -// copy-initialization: argument-passing (8.5.12) -void helper ( boost::optional ) ; -void test_explicit_constructor() -{ - helper(3) ; // ERROR: Ctor is explicit. -} -#else -void test_explicit_constructor() -{ - boost::optional opt = 3 ; // ERROR: Ctor is explicit. -} -#endif - - diff --git a/test/optional_test_fail3a.cpp b/test/optional_test_fail3a.cpp deleted file mode 100644 index 6204853..0000000 --- a/test/optional_test_fail3a.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (C) 2003, Fernando Luis Cacciola Carballal. -// -// Use, modification, and distribution is 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) -// -// See http://www.boost.org/lib/optional for documentation. -// -// You are welcome to contact the author at: -// fernando_cacciola@hotmail.com -// -#include - -#include "boost/optional.hpp" - -// -// THIS TEST SHOULD FAIL TO COMPILE -// -void test_no_unsupported_conversion() -{ - boost::optional opt1(1) ; - boost::optional< std::string > opt2( opt1 ) ; // Cannot convert from "int" to "std::string" -} - - diff --git a/test/optional_test_fail3b.cpp b/test/optional_test_fail3b.cpp deleted file mode 100644 index a7d2f1a..0000000 --- a/test/optional_test_fail3b.cpp +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (C) 2003, Fernando Luis Cacciola Carballal. -// -// Use, modification, and distribution is 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) -// -// See http://www.boost.org/lib/optional for documentation. -// -// You are welcome to contact the author at: -// fernando_cacciola@hotmail.com -// -#include - -#include "boost/optional.hpp" - -// -// THIS TEST SHOULD FAIL TO COMPILE -// -void test_no_unsupported_conversion() -{ - boost::optional opt1(1) ; - boost::optional< std::string > opt2 ; - opt2 = opt1 ; // Cannot convert from "int" to "std::string" -} - - diff --git a/test/optional_test_inplace.cpp b/test/optional_test_inplace.cpp deleted file mode 100644 index b56ad1c..0000000 --- a/test/optional_test_inplace.cpp +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright (C) 2003, Fernando Luis Cacciola Carballal. -// -// Use, modification, and distribution is 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) -// -// See http://www.boost.org/lib/optional for documentation. -// -// You are welcome to contact the author at: -// fernando_cacciola@hotmail.com -// -#include -#include -#include - -#define BOOST_ENABLE_ASSERT_HANDLER - -#include "boost/optional.hpp" - -#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT -#include "boost/detail/in_place_factory.hpp" -#include "boost/detail/typed_in_place_factory.hpp" -#endif - -#ifdef __BORLANDC__ -#pragma hdrstop -#endif - -#include "boost/test/minimal.hpp" - -#include "optional_test_common.cpp" - -#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT -struct A -{ - A ( double a0, std::string a1 ) : m_a0(a0), m_a1(a1) {} - - friend bool operator == ( A const& x, A const& y ) - { return x.m_a0 == y.m_a0 && x.m_a1 == y.m_a1 ; } - - double m_a0 ; - std::string m_a1 ; -} ; - -int test_main( int, char* [] ) -{ - double a00 = 3.14, a10 = 6.02e-23; - std::string a01("pi"), a11("mol"); - - A a0(a00,a01); - A a1(a10,a11); - - boost::optional opt1(a0); - - boost::optional opt2 ( boost::in_place(a00,a01) ) ; - - boost::optional opt3 ( boost::in_place(a00,a01) ) ; - - BOOST_CHECK( opt1 == opt2 ) ; - BOOST_CHECK( opt2 == opt2 ) ; - BOOST_CHECK( *opt2 == a0 ) ; - - opt2 = boost::in_place(a10,a11); - BOOST_CHECK( *opt2 == a1 ) ; - - opt3 = boost::in_place(a10,a11); - BOOST_CHECK( *opt3 == a1 ) ; - - return 0; -} -#else -int test_main( int, char* [] ) -{ - // If in-place factories are not supported there is nothing to test - return 0 ; -} -#endif - - - diff --git a/test/optional_test_inplace_fail.cpp b/test/optional_test_inplace_fail.cpp deleted file mode 100644 index 2b75410..0000000 --- a/test/optional_test_inplace_fail.cpp +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (C) 2003, Fernando Luis Cacciola Carballal. -// -// Use, modification, and distribution is 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) -// -// See http://www.boost.org/lib/optional for documentation. -// -// You are welcome to contact the author at: -// fernando_cacciola@hotmail.com -// -#include -#include -#include - -#define BOOST_ENABLE_ASSERT_HANDLER - -#include "boost/optional.hpp" - -#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT -#include "boost/detail/in_place_factory.hpp" -#endif - -#ifdef __BORLANDC__ -#pragma hdrstop -#endif - -#include "boost/test/minimal.hpp" - -#include "optional_test_common.cpp" - -#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT -struct A -{ - A ( double a0, std::string a1 ) : m_a0(a0), m_a1(a1) {} - - friend bool operator == ( A const& x, A const& y ) - { return x.m_a0 == y.m_a0 && x.m_a1 == y.m_a1 ; } - - double m_a0 ; - std::string m_a1 ; -} ; - -int test_main( int, char* [] ) -{ - int invalid_extra_parameter ; - boost::optional opt2 ( boost::in_place(3.14,"pi",invalid_extra_parameter) ) ; - - return 0; -} -#else -int test_main( int, char* [] ) -{ - int invalid_extra_parameter ; - boost::optional opt2 ( A(3.14,"pi",invalid_extra_parameter) ) ; - - return 0; -} -#endif - diff --git a/test/optional_test_inplace_fail2.cpp b/test/optional_test_inplace_fail2.cpp deleted file mode 100644 index 8435a56..0000000 --- a/test/optional_test_inplace_fail2.cpp +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (C) 2003, Fernando Luis Cacciola Carballal. -// -// Use, modification, and distribution is 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) -// -// See http://www.boost.org/lib/optional for documentation. -// -// You are welcome to contact the author at: -// fernando_cacciola@hotmail.com -// -#include -#include -#include - -#define BOOST_ENABLE_ASSERT_HANDLER - -#include "boost/optional.hpp" - -#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT -#include "boost/detail/typed_in_place_factory.hpp" -#endif - -#ifdef __BORLANDC__ -#pragma hdrstop -#endif - -#include "boost/test/minimal.hpp" - -#include "optional_test_common.cpp" - -#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT -struct A -{ - A ( double a0, std::string a1 ) : m_a0(a0), m_a1(a1) {} - - friend bool operator == ( A const& x, A const& y ) - { return x.m_a0 == y.m_a0 && x.m_a1 == y.m_a1 ; } - - double m_a0 ; - std::string m_a1 ; -} ; - -int test_main( int, char* [] ) -{ - // This must fail to compile. - // The first template argument to in_place<> is the target-type, - // not the first constructor parameter type. - boost::optional opt2 ( boost::in_place(3.14,"pi") ) ; - - return 0; -} -#else -int test_main( int, char* [] ) -{ - boost::optional opt2 ( int(3.14) ) ; - - return 0; -} -#endif - - diff --git a/test/optional_test_ref.cpp b/test/optional_test_ref.cpp deleted file mode 100644 index 4cf2506..0000000 --- a/test/optional_test_ref.cpp +++ /dev/null @@ -1,323 +0,0 @@ -// Copyright (C) 2003, Fernando Luis Cacciola Carballal. -// -// Use, modification, and distribution is 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) -// -// See http://www.boost.org/lib/optional for documentation. -// -// You are welcome to contact the author at: -// fernando_cacciola@hotmail.com -// -#include -#include -#include - -#define BOOST_ENABLE_ASSERT_HANDLER - -#include "boost/optional.hpp" - -#ifdef __BORLANDC__ -#pragma hdrstop -#endif - -#include "boost/none.hpp" - -#include "boost/test/minimal.hpp" - -#include "optional_test_common.cpp" - -template -inline void check_ref_uninitialized_const ( optional const& opt ) -{ -#ifndef BOOST_OPTIONAL_NO_NULL_COMPARE - BOOST_CHECK( opt == 0 ) ; -#endif - BOOST_CHECK( !opt ) ; -} -template -inline void check_ref_uninitialized ( optional& opt ) -{ -#ifndef BOOST_OPTIONAL_NO_NULL_COMPARE - BOOST_CHECK( opt == 0 ) ; -#endif - BOOST_CHECK( !opt ) ; - - check_ref_uninitialized_const(opt); -} - -template -inline void check_ref_initialized_const ( optional const& opt ) -{ - BOOST_CHECK( opt ) ; - -#ifndef BOOST_OPTIONAL_NO_NULL_COMPARE - BOOST_CHECK( opt != 0 ) ; -#endif - - BOOST_CHECK ( !!opt ) ; -} - -template -inline void check_ref_initialized ( optional& opt ) -{ - BOOST_CHECK( opt ) ; - -#ifndef BOOST_OPTIONAL_NO_NULL_COMPARE - BOOST_CHECK( opt != 0 ) ; -#endif - - BOOST_CHECK ( !!opt ) ; - - check_ref_initialized_const(opt); -} - -template -inline void check_ref_value_const ( optional const& opt, T const& v, T const& z ) -{ - BOOST_CHECK( *opt == v ) ; - BOOST_CHECK( *opt != z ) ; - BOOST_CHECK( opt.get() == v ) ; - BOOST_CHECK( opt.get() != z ) ; -} - -template -inline void check_ref_value ( optional& opt, T const& v, T const& z ) -{ - BOOST_CHECK( *opt == v ) ; - BOOST_CHECK( *opt != z ) ; - BOOST_CHECK( opt.get() == v ) ; - BOOST_CHECK( opt.get() != z ) ; - - check_ref_value_const(opt,v,z); -} - -// -// Basic test. -// Check ordinary functionality: -// Initialization, assignment, comparison and value-accessing. -// -template -void test_basics( T const* ) -{ - TRACE( std::endl << BOOST_CURRENT_FUNCTION ); - - T z(0); - - T a(1); - - T& aref = a ; - - // Default construction. - // 'def' state is Uninitialized. - // T::T() is not called - optional def ; - check_ref_uninitialized(def); - - // Direct initialization. - // 'oa' state is Initialized with 'a' - // T::T( T const& x ) is NOT used becasue the optional holds a reference. - set_pending_copy( ARG(T) ) ; - optional oa ( aref ) ; - check_is_pending_copy( ARG(T) ); - check_ref_initialized(oa); - check_ref_value(oa,a,z); - - // Copy initialization. - // T::T ( T const& x ) is NOT used becasue the optional holds a reference. - set_pending_copy( ARG(T) ) ; - optional const oa2 ( oa ) ; - check_is_pending_copy( ARG(T) ) ; - check_ref_initialized_const(oa2); - check_ref_value_const(oa2,a,z); - - T b(2); - optional ob ; - - // Value-Assignment upon Uninitialized optional. - // T::T ( T const& x ) is NOT used becasue the optional holds a reference. - set_pending_copy( ARG(T) ) ; - ob = a ; - check_is_pending_copy( ARG(T) ) ; - check_ref_initialized(ob); - check_ref_value(ob,a,z); - - // Value-Assignment upon Initialized optional. - // T::T ( T const& x ) is NOT used becasue the optional holds a reference. - set_pending_dtor( ARG(T) ) ; - set_pending_copy( ARG(T) ) ; - ob = b ; - check_is_pending_dtor( ARG(T) ) ; - check_is_pending_copy( ARG(T) ) ; - check_ref_initialized(ob); - check_ref_value(ob,b,z); - - // Assignment initialization. - // T::T ( T const& x ) is NOT used becasue the optional holds a reference. - set_pending_copy( ARG(T) ) ; - optional const oa3 = b ; - check_is_pending_copy( ARG(T) ) ; - check_ref_initialized_const(oa3); - check_ref_value_const(oa3,b,z); - - - // Assignment - // T::~T() is used to destroy previous value in ob. - // T::T ( T const& x ) is NOT used becasue the optional holds a reference. - set_pending_dtor( ARG(T) ) ; - set_pending_copy( ARG(T) ) ; - oa = ob ; - check_is_pending_dtor( ARG(T) ) ; - check_is_pending_copy( ARG(T) ) ; - check_ref_initialized(oa); - check_ref_value(oa,b,z); - - // Uninitializing Assignment upon Initialized Optional - // T::~T() is NOT used becasue the optional holds a reference. - set_pending_dtor( ARG(T) ) ; - set_pending_copy( ARG(T) ) ; - oa = def ; - check_is_pending_dtor( ARG(T) ) ; - check_is_pending_copy( ARG(T) ) ; - check_ref_uninitialized(oa); - - // Uninitializing Assignment upon Uninitialized Optional - // (Dtor is not called this time) - set_pending_dtor( ARG(T) ) ; - set_pending_copy( ARG(T) ) ; - oa = def ; - check_is_pending_dtor( ARG(T) ) ; - check_is_pending_copy( ARG(T) ) ; - check_ref_uninitialized(oa); - - // Deinitialization of Initialized Optional - // T::~T() is NOT used becasue the optional holds a reference. - set_pending_dtor( ARG(T) ) ; - ob.reset(); - check_is_pending_dtor( ARG(T) ) ; - check_ref_uninitialized(ob); - - // Deinitialization of Uninitialized Optional - // T::~T() is not called this time - set_pending_dtor( ARG(T) ) ; - ob.reset(); - check_is_pending_dtor( ARG(T) ) ; - check_ref_uninitialized(ob); -} - -// -// This verifies relational operators. -// -template -void test_relops( T const* ) -{ - TRACE( std::endl << BOOST_CURRENT_FUNCTION ); - - reset_throw_on_copy( ARG(T) ) ; - - T v0(18); - T v1(19); - T v2(19); - - optional def0 ; - optional def1 ; - optional opt0(v0); - optional opt1(v1); - optional opt2(v2); - - // Check identity - BOOST_CHECK ( def0 == def0 ) ; - BOOST_CHECK ( opt0 == opt0 ) ; - BOOST_CHECK ( !(def0 != def0) ) ; - BOOST_CHECK ( !(opt0 != opt0) ) ; - - // Check when both are uininitalized. - BOOST_CHECK ( def0 == def1 ) ; // both uninitialized compare equal - BOOST_CHECK ( !(def0 < def1) ) ; // uninitialized is never less than uninitialized - BOOST_CHECK ( !(def0 > def1) ) ; // uninitialized is never greater than uninitialized - BOOST_CHECK ( !(def0 != def1) ) ; - BOOST_CHECK ( def0 <= def1 ) ; - BOOST_CHECK ( def0 >= def1 ) ; - - // Check when only lhs is uninitialized. - BOOST_CHECK ( def0 != opt0 ) ; // uninitialized is never equal to initialized - BOOST_CHECK ( !(def0 == opt0) ) ; - BOOST_CHECK ( def0 < opt0 ) ; // uninitialized is always less than initialized - BOOST_CHECK ( !(def0 > opt0) ) ; - BOOST_CHECK ( def0 <= opt0 ) ; - BOOST_CHECK ( !(def0 >= opt0) ) ; - - // Check when only rhs is uninitialized. - BOOST_CHECK ( opt0 != def0 ) ; // initialized is never equal to uninitialized - BOOST_CHECK ( !(opt0 == def0) ) ; - BOOST_CHECK ( !(opt0 < def0) ) ; // initialized is never less than uninitialized - BOOST_CHECK ( opt0 > def0 ) ; - BOOST_CHECK ( !(opt0 <= def0) ) ; - BOOST_CHECK ( opt0 >= opt0 ) ; - - // If both are initialized, values are compared - BOOST_CHECK ( opt0 != opt1 ) ; - BOOST_CHECK ( opt1 == opt2 ) ; - BOOST_CHECK ( opt0 < opt1 ) ; - BOOST_CHECK ( opt1 > opt0 ) ; - BOOST_CHECK ( opt1 <= opt2 ) ; - BOOST_CHECK ( opt1 >= opt0 ) ; -} - -template -void test_none( T const* ) -{ - TRACE( std::endl << BOOST_CURRENT_FUNCTION ); - - using boost::none ; - - T a(1234); - - optional def0 ; - optional def1(none) ; - optional non_def(a) ; - - BOOST_CHECK ( def0 == none ) ; - BOOST_CHECK ( non_def != none ) ; - BOOST_CHECK ( !def1 ) ; - - non_def = none ; - BOOST_CHECK ( !non_def ) ; -} - -void test_with_builtin_types() -{ - TRACE( std::endl << BOOST_CURRENT_FUNCTION ); - - test_basics( ARG(double) ); - test_relops( ARG(double) ) ; - test_none ( ARG(double) ) ; -} - -void test_with_class_type() -{ - TRACE( std::endl << BOOST_CURRENT_FUNCTION ); - - test_basics( ARG(X) ); - test_relops( ARG(X) ) ; - test_none ( ARG(X) ) ; - - BOOST_CHECK ( X::count == 0 ) ; -} - -int test_main( int, char* [] ) -{ - try - { - test_with_class_type(); - test_with_builtin_types(); - } - catch ( ... ) - { - BOOST_ERROR("Unexpected Exception caught!"); - } - - return 0; -} - - diff --git a/test/optional_test_ref_fail1.cpp b/test/optional_test_ref_fail1.cpp deleted file mode 100644 index 1842741..0000000 --- a/test/optional_test_ref_fail1.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (C) 2003, Fernando Luis Cacciola Carballal. -// -// Use, modification, and distribution is 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) -// -// See http://www.boost.org/lib/optional for documentation. -// -// You are welcome to contact the author at: -// fernando_cacciola@hotmail.com -// -#include "boost/optional.hpp" - -// -// THIS TEST SHOULD FAIL TO COMPILE -// -void optional_reference__test_no_converting_assignment() -{ - boost::optional opt ; - short v = 1 ; - short& r = v ; - opt = r ; -} - - diff --git a/test/optional_test_ref_fail2.cpp b/test/optional_test_ref_fail2.cpp deleted file mode 100644 index 732c995..0000000 --- a/test/optional_test_ref_fail2.cpp +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (C) 2003, Fernando Luis Cacciola Carballal. -// -// Use, modification, and distribution is 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) -// -// See http://www.boost.org/lib/optional for documentation. -// -// You are welcome to contact the author at: -// fernando_cacciola@hotmail.com -// -#include "boost/optional.hpp" - -// -// THIS TEST SHOULD FAIL TO COMPILE -// -void optional_reference__test_no_ptr_access() -{ - boost::optional opt ; - opt.get_ptr(); -} - - diff --git a/test/optional_test_ref_fail3.cpp b/test/optional_test_ref_fail3.cpp deleted file mode 100644 index e630d07..0000000 --- a/test/optional_test_ref_fail3.cpp +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (C) 2003, Fernando Luis Cacciola Carballal. -// -// Use, modification, and distribution is 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) -// -// See http://www.boost.org/lib/optional for documentation. -// -// You are welcome to contact the author at: -// fernando_cacciola@hotmail.com -// -#include "boost/optional.hpp" - -// -// THIS TEST SHOULD FAIL TO COMPILE -// -void optional_reference__test_no_converting_ctor() -{ - boost::optional opt1 ; - boost::optional opt2 = opt1 ; -} - - diff --git a/test/optional_test_ref_fail4.cpp b/test/optional_test_ref_fail4.cpp deleted file mode 100644 index 0425243..0000000 --- a/test/optional_test_ref_fail4.cpp +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (C) 2003, Fernando Luis Cacciola Carballal. -// -// Use, modification, and distribution is 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) -// -// See http://www.boost.org/lib/optional for documentation. -// -// You are welcome to contact the author at: -// fernando_cacciola@hotmail.com -// -#include "boost/optional.hpp" - -// -// THIS TEST SHOULD FAIL TO COMPILE -// -void optional_reference__test_no_converting_initialization() -{ - short v = 1 ; - short& r = v; - boost::optional opt(r) ; -} - - diff --git a/test/optional_test_tie.cpp b/test/optional_test_tie.cpp deleted file mode 100644 index c4fc4ed..0000000 --- a/test/optional_test_tie.cpp +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (C) 2003, Fernando Luis Cacciola Carballal. -// -// Use, modification, and distribution is 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) -// -// See http://www.boost.org/lib/optional for documentation. -// -// You are welcome to contact the author at: -// fernando_cacciola@hotmail.com -// -#include -#include -#include - -#define BOOST_ENABLE_ASSERT_HANDLER - -#include "boost/optional.hpp" -#include "boost/tuple/tuple.hpp" - -#ifdef __BORLANDC__ -#pragma hdrstop -#endif - -#include "boost/test/minimal.hpp" - -#include "optional_test_common.cpp" - -// Test boost::tie() interoperabiliy. -int test_main( int, char* [] ) -{ - typedef X T ; - - try - { - TRACE( std::endl << BOOST_CURRENT_FUNCTION ); - - T z(0); - T a(1); - T b(2); - - optional oa, ob ; - - // T::T( T const& x ) is used - set_pending_dtor( ARG(T) ) ; - set_pending_copy( ARG(T) ) ; - boost::tie(oa,ob) = std::make_pair(a,b) ; - check_is_not_pending_dtor( ARG(T) ) ; - check_is_not_pending_copy( ARG(T) ) ; - check_initialized(oa); - check_initialized(ob); - check_value(oa,a,z); - check_value(ob,b,z); - - } - catch ( ... ) - { - BOOST_ERROR("Unexpected Exception caught!"); - } - - return 0; -} - -