2011-04-06 21:56:23 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								[/
							 
						 
					
						
							
								
									
										
										
										
											2007-05-29 06:40:25 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    Boost.Optional
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    Copyright (c) 2003-2007 Fernando Luis Cacciola Carballal
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    Distributed under the Boost Software License, Version 1.0.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    (See accompanying file LICENSE_1_0.txt or copy at
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    http://www.boost.org/LICENSE_1_0.txt)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-06-04 18:13:06 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								[section Design Overview]
							 
						 
					
						
							
								
									
										
										
										
											2007-05-29 06:40:25 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								[section The models]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								In C++, we can ['declare] an object (a variable) of type `T`, and we can give this
							 
						 
					
						
							
								
									
										
										
										
											2014-06-03 17:36:18 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								variable an ['initial value] (through an ['initializer]. (cf. 8.5)).
							 
						 
					
						
							
								
									
										
										
										
											2007-05-29 06:40:25 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								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 initial value]
							 
						 
					
						
							
								
									
										
										
										
											2014-06-03 17:36:18 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								(cf. 8.5/11).
							 
						 
					
						
							
								
									
										
										
										
											2007-05-29 06:40:25 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								`optional<T>` intends to formalize the notion of initialization (or lack of it)
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								allowing a program to test whether an object has been initialized and stating
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								that access to the value of an uninitialized object is undefined behavior. 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 behavior] 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
							 
						 
					
						
							
								
									
										
										
										
											2014-06-03 17:36:18 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								`T` plus some ['nil_t]—where `nil_t` is some stateless POD—can be modeled in modern
							 
						 
					
						
							
								
									
										
										
										
											2007-05-29 06:40:25 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								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 precedent for a discriminated union as a model for an optional value:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								the __HASKELL__ [*Maybe] built-in 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 necessary 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.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-04-06 21:56:23 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								As of this writing I don't know of any precedent for a variable-size
							 
						 
					
						
							
								
									
										
										
										
											2007-05-29 06:40:25 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								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 behavior 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 behavior
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								of trying to access the value of an uninitialized optional
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								[endsect]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								[section 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 built-in 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 new yet equivalent wrapped object.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								* [*Direct Value Assignment (upon initialized):] To assign a value to the
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								wrapped object.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								* [*Direct Value Assignment (upon uninitialized):] To initialize the wrapped
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								object with a value obtained as a copy of some object.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								* [*Assignment (upon initialized):] To assign to the wrapped object the value
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								of another wrapped object.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								* [*Assignment (upon uninitialized):] To initialize the wrapped object with
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								value of another wrapped object.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								* [*Deep Relational Operations (when supported by the type T):] To compare
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								wrapped object values taking into account the presence of uninitialized states.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								* [*Value access:] To unwrap the wrapped object.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								* [*Initialization state query:] To determine if the object is formally
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								initialized or not.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								* [*Swap:] To exchange wrapped objects. (with whatever exception safety
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								guarantees 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.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								[endsect]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								[section 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 chosen (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.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								[heading Lexically-hinted Value Access in the presence of possibly
							 
						 
					
						
							
								
									
										
										
										
											2015-03-13 22:53:47 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								uninitialized optional objects: The operators * and ->]
							 
						 
					
						
							
								
									
										
										
										
											2007-05-29 06:40:25 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								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
							 
						 
					
						
							
								
									
										
										
										
											2011-04-06 21:56:23 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								the notion of nonexistent objects.
							 
						 
					
						
							
								
									
										
										
										
											2007-05-29 06:40:25 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								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,
							 
						 
					
						
							
								
									
										
										
										
											2011-04-06 21:56:23 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								possibly nonexistent) objects; particularly as optional arguments to a
							 
						 
					
						
							
								
									
										
										
										
											2007-05-29 06:40:25 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								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 __OPTIONAL_POINTEE__ concept.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								This concept captures the syntactic usage of operators `*`, `->` and
							 
						 
					
						
							
								
									
										
										
										
											2014-06-03 17:36:18 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								contextual conversion to `bool` to convey the notion of optionality.
							 
						 
					
						
							
								
									
										
										
										
											2007-05-29 06:40:25 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								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 built-in 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 inappropriate 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
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								__OPTIONAL_POINTEE__ concept incarnated by pointers.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								[heading Optional<T> as a model of OptionalPointee]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								For value access operations `optional<>` uses operators `*` and `->` to
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								lexically warn about the possibly uninitialized state appealing to the
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								familiar pointer semantics w.r.t. to null pointers.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-02-18 23:18:01 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								[caution
							 
						 
					
						
							
								
									
										
										
										
											2007-05-29 06:40:25 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								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<>` does not have shallow-copy so does not alias:
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								two different optionals never refer to the ['same] value unless `T` itself is
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								a reference (but may 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 __FUNCTION_EQUAL_POINTEES__ and __FUNCTION_LESS_POINTEES__ instead.
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								[endsect]
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								[endsect]