mirror of
https://github.com/boostorg/optional.git
synced 2025-07-29 12:07:21 +02:00
Merge branch 'develop'
Conflicts: doc/html/index.html
This commit is contained in:
@ -46,23 +46,43 @@ Distributed under the Boost Software License, Version 1.0.
|
||||
|
||||
|
||||
[section Introduction]
|
||||
This library can be used to represent 'optional' (or 'nullable') objects that can be safely passed by value:
|
||||
Class template `optional` is a wrapper for representing 'optional' (or 'nullable') objects who may not (yet) contain a valid value. Optional objects offer full value semantics; they are good for passing by value and usage inside STL containers. This is a header-only library.
|
||||
|
||||
optional<int> readInt(); // this function may return either an int or a not-an-int
|
||||
[heading Problem]
|
||||
Suppose we want to read a parameter form a config file which represents some integral value, let's call it `"MaxValue"`. It is possible that this parameter is not specified; such situation is no error. It is valid to not specify the parameter and in that case the program is supposed to behave slightly different. Also suppose that any possible value of type `int` is a valid value for `"MaxValue"`, so we cannot jut use `-1` to represent the absence of the parameter in the config file.
|
||||
|
||||
if (optional<int> oi = readInt()) // did I get a real int
|
||||
cout << "my int is: " << *oi; // use my int
|
||||
else
|
||||
cout << "I have no int";
|
||||
|
||||
[heading Solution]
|
||||
|
||||
This is how you solve it with `boost::optional`:
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
boost::optional<int> getConfigParam(std::string name); // return either an int or a `not-an-int`
|
||||
|
||||
int main()
|
||||
{
|
||||
if (boost::optional<int> oi = getConfigParam("MaxValue")) // did I get a real int?
|
||||
runWithMax(*oi); // use my int
|
||||
else
|
||||
runWithNoMax();
|
||||
}
|
||||
|
||||
[endsect]
|
||||
|
||||
[include motivation.qbk]
|
||||
[include development.qbk]
|
||||
[include reference.qbk]
|
||||
[include examples.qbk]
|
||||
[include special_cases.qbk]
|
||||
[include dependencies.qbk]
|
||||
[include acknowledgments.qbk]
|
||||
[include 01_quick_start.qbk]
|
||||
[section Tutorial]
|
||||
[include 12_motivation.qbk]
|
||||
[include 13_development.qbk]
|
||||
[include 14_optional_references.qbk]
|
||||
[include 15_in_place_factories.qbk]
|
||||
[include 16_optional_bool.qbk]
|
||||
[include 17_exception_safety.qbk]
|
||||
[include 18_type_requirements.qbk]
|
||||
[endsect]
|
||||
[section Reference]
|
||||
[include 20_reference.qbk]
|
||||
[endsect]
|
||||
[include 90_dependencies.qbk]
|
||||
[include 91_acknowledgments.qbk]
|
||||
|
||||
|
146
doc/01_quick_start.qbk
Normal file
146
doc/01_quick_start.qbk
Normal file
@ -0,0 +1,146 @@
|
||||
[/
|
||||
Boost.Optional
|
||||
|
||||
Copyright (c) 2003-2007 Fernando Luis Cacciola Carballal
|
||||
Copyright (c) 2014 Andrzej Krzemienski
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
]
|
||||
|
||||
|
||||
[section Quick Start]
|
||||
|
||||
[section Optional return values]
|
||||
|
||||
Let's write and use a converter function that converts an a `std::string` to an `int`. It is possible that for a given string (e.g. `"cat"`) there exist no value of type `int` capable of representing the conversion result. We do not consider such situation an error. We expect that the converter can be used only to check if the conversion is possible. A natural signature for this function can be:
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
boost::optionl<int> convert(const std::string& text);
|
||||
|
||||
All necessary functionality can be included with one header `<boost/optional.hpp>`. The above function signature means that the function can either return a value of type `int` or a flag indicating that no value of `int` is available. This does not indicate an error. It is like one additional value of `int`. This is how we can use our function:
|
||||
|
||||
const std::string& text = /*... */;
|
||||
boost::optionl<int> oi = convert(text); // move-construct
|
||||
if (oi) // contextual conversion to bool
|
||||
int i = *oi; // operator*
|
||||
|
||||
In order to test if `optional` contains a value, we use the contextual conversion to type `bool`. Because of this we can combine the initialization of the optional object and the test into one instruction:
|
||||
|
||||
if (boost::optionl<int> oi = convert(text))
|
||||
int i = *oi;
|
||||
|
||||
We extract the contained value with `operator*` (and with `operator->` where it makes sense). An attempt to extract the contained value of an uninitialized optional object is an ['undefined behaviour] (UB). This implementation guards the call with `BOOST_ASSERT`. Therefore you should be sure that the contained value is there before extracting. For instance, the following code is reasonably UB-safe:
|
||||
|
||||
int i = *convert("100");
|
||||
|
||||
This is because we know that string value `"100"` converts to a valid value of `int`. If you do not like this potential UB, you can use an alternative way of extracting the contained value:
|
||||
|
||||
try {
|
||||
int j = convert(text).value();
|
||||
}
|
||||
catch (const boost::bad_optional_access&) {
|
||||
// deal with it
|
||||
}
|
||||
|
||||
This version throws an exception upon an attempt to access a non-existent contained value. If your way of dealing with the missing value is to use some default, like `0`, there exists a yet another alternative:
|
||||
|
||||
int k = convert(text).value_or(0);
|
||||
|
||||
This uses the `atoi`-like approach to conversions: if `text` does not represent an integral number just return `0`. Now, let's consider how function `convert` can be implemented.
|
||||
|
||||
boost::optionl<int> convert(const std::string& text)
|
||||
{
|
||||
std::stringstream s(text);
|
||||
int i;
|
||||
if ((s >> i) && s.get() == std::char_traits<char>::eof())
|
||||
return i;
|
||||
else
|
||||
return boost::none;
|
||||
}
|
||||
|
||||
Observe the two return statements. `return i` uses the converting constructor that can create `optional<T>` from `T`. Thus constructed optional object is initialized and its value is a copy of `i`. The other return statement uses another converting constructor from a special tag `boost::none`. It is used to indicate that we want to create an uninitialized optional object.
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Optional automatic variables]
|
||||
|
||||
We could write function `convert` in a slightly different manner, so that it has a single `return`-statement:
|
||||
|
||||
boost::optionl<int> convert(const std::string& text)
|
||||
{
|
||||
boost::optionl<int> ans;
|
||||
std::stringstream s(text);
|
||||
int i;
|
||||
if ((s >> i) && s.get() == std::char_traits<char>::eof())
|
||||
ans = i;
|
||||
|
||||
return ans;
|
||||
}
|
||||
|
||||
The default constructor of `optional` creates an unitialized optional object. Unlike with `int`s you cannot have an `optional<int>` in an indeterminate state. Its state is always well defined. Instruction `ans = i` initializes the optional object. It uses the assignment from `int`. In general, for `optional<T>`, when an assignment from `T` is invoked, it can do two things. If the optional object is not initialized our case here), it initializes it with `T`'s copy constructor. If the optional object is already initialized, it assigns the new value to it using `T`'s copy assignment.
|
||||
[endsect]
|
||||
|
||||
[section Optional data members]
|
||||
|
||||
Suppose we want to implement a ['lazy load] optimization. This is because we do not want to perform an expensive initialization of our `Resource` until (if at all) it is really used. We can do it this way:
|
||||
|
||||
class Widget
|
||||
{
|
||||
boost::optional<Resource> resource_;
|
||||
|
||||
public:
|
||||
Widget() {}
|
||||
|
||||
Resource& getResource() // not thread-safe
|
||||
{
|
||||
if (resource_ == boost::none)
|
||||
resource_.emplace("resource", "arguments");
|
||||
|
||||
return *resource_;
|
||||
}
|
||||
};
|
||||
|
||||
`optional`'s default constructor creates an uninitialized optional. No call to `Resource`'s default constructor is attempted. `Resource` doesn't have to be __SGI_DEFAULT_CONSTRUCTIBLE__. In function `getResource` we first check if `resource_` is initialized. This time we do not use the contextual conversion to `bool`, but a comparison with `boost::none`. These two ways are equivalent. Function `emplace` initializes the optional in-place by perfect-forwarding the arguments to the constructor of `Resource`. No copy- or move-construction is involved here. `Resource` doesn't even have to be `MoveConstructible`.
|
||||
|
||||
[note Function `emplace` is only available on compilers that support rvalue references and variadic templates. If your compiler does not support these features and you still need to avoid any move-constructions, use [link boost_optional.tutorial.in_place_factories In-Place Factories].]
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Bypassing unnecessary default construction]
|
||||
|
||||
Suppose we have class `Date`, which does not have a default constructor: there is no good candidate for a default date. We have a function that returns two dates in form of a `boost::tuple`:
|
||||
|
||||
boost::tuple<Date, Date> getPeriod();
|
||||
|
||||
In other place we want to use the result of `getPeriod`, but want the two dates to be named: `begin` and `end`. We want to implement something like 'multiple return values':
|
||||
|
||||
Date begin, end; // Error: no default ctor!
|
||||
boost::tie(begin, end) = getPeriod();
|
||||
|
||||
The second line works already, this is the capability of Boost.Tuple library, but the first line won't work. We could set some invented initial dates, but it is confusing and may be an unacceptable cost, given that these values will be overwritten in the next line anyway. This is where `optional` can help:
|
||||
|
||||
boost::optional<Date> begin, end;
|
||||
boost::tie(begin, end) = getPeriod();
|
||||
|
||||
It works because inside `boost::tie` a move-assignment from `T` is invoked on `optional<T>`, which internally calls a move-constructor of `T`.
|
||||
[endsect]
|
||||
|
||||
[section Storage in containers]
|
||||
|
||||
Suppose you want to ask users to choose some number (an `int`). One of the valid responses is to choose nothing, which is represented by an uninitialized `optional<int>`. You want to make a histogram showing how many times each choice was made. You can use an `std::map`:
|
||||
|
||||
std::map<boost::optional<int>, int> choices;
|
||||
|
||||
for (int i = 0; i < LIMIT; ++i) {
|
||||
boost::optional<int> choice = readChoice();
|
||||
++choices[choice];
|
||||
}
|
||||
|
||||
This works because `optional<T>` is `LessThanComparable` whenever `T` is `LessThanComparable`. In this case the state of being uninitialized is treated as a yet another value of `T`, which is compared less than any value of `T`. So the set of values that type `optional<T>` can assume is {`boost::none`, -2147483648, -2147483647, ..., -1, 0, 1, ..., 2147483647} (assuming a 32-bit `int`).
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
@ -77,4 +77,4 @@ without ever checking if it has a valid value.
|
||||
|
||||
Clearly, we need a better idiom.
|
||||
|
||||
[endsect]
|
||||
[endsect]
|
@ -8,18 +8,18 @@
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
]
|
||||
|
||||
[section Development]
|
||||
[section Design Overview]
|
||||
|
||||
[section 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)).
|
||||
variable an ['initial value] (through an ['initializer]. (cf. 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 initial value]
|
||||
(c.f. 8.5.9).
|
||||
(cf. 8.5/11).
|
||||
`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
|
||||
@ -38,7 +38,7 @@ 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
|
||||
`T` plus some ['nil_t]—where `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`.
|
||||
@ -197,7 +197,7 @@ 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
|
||||
conversion to `bool` to convey the notion of optionality.
|
||||
contextual 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
|
120
doc/14_optional_references.qbk
Normal file
120
doc/14_optional_references.qbk
Normal file
@ -0,0 +1,120 @@
|
||||
|
||||
[section Optional references]
|
||||
|
||||
This library allows 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:
|
||||
|
||||
* Converting constructors
|
||||
* Converting assignment
|
||||
* InPlace construction
|
||||
* InPlace assignment
|
||||
* Value-access via pointer
|
||||
|
||||
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:
|
||||
|
||||
* Copies of `optional<T&>` will copy the references but all these references
|
||||
will nonetheless refer to the same object.
|
||||
* Value-access will actually provide access to the referenced object
|
||||
rather than the reference itself.
|
||||
|
||||
[warning On compilers that do not conform to Standard C++ rules of reference binding, operations on optional references might give adverse results: rather than binding a reference to a designated object they may create an unexpected temporary and bind to it. For more details see [link boost_optional.dependencies_and_portability.optional_reference_binding Dependencies and Portability section].]
|
||||
|
||||
[heading Rvalue references]
|
||||
|
||||
Rvalue references and lvalue references to const have the ability in C++ to extend the life time of a temporary they bind to. Optional references do not have this capability, therefore to avoid surprising effects it is not possible to initialize an optional references from a temporary. Optional rvalue references are disabled altogether. Also, the initialization and assignment of an optional reference to const from rvalue reference is disabled.
|
||||
|
||||
const int& i = 1; // legal
|
||||
optional<const int&> oi = 1; // illegal
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Rebinding semantics for assignment of optional references]
|
||||
|
||||
If you assign to an ['uninitialized ] `optional<T&>` the effect is to bind (for
|
||||
the first time) to the object. Clearly, there is no other choice.
|
||||
|
||||
int x = 1 ;
|
||||
int& rx = x ;
|
||||
optional<int&> ora ;
|
||||
optional<int&> orb(x) ;
|
||||
ora = orb ; // now 'ora' is bound to 'x' through 'rx'
|
||||
*ora = 2 ; // Changes value of 'x' through 'ora'
|
||||
assert(x==2);
|
||||
|
||||
If you assign to a bare C++ reference, the assignment is forwarded to the
|
||||
referenced object; its value changes but the reference is never rebound.
|
||||
|
||||
int a = 1 ;
|
||||
int& ra = a ;
|
||||
int b = 2 ;
|
||||
int& rb = b ;
|
||||
ra = rb ; // Changes the value of 'a' to 'b'
|
||||
assert(a==b);
|
||||
b = 3 ;
|
||||
assert(ra!=b); // 'ra' is not rebound to 'b'
|
||||
|
||||
Now, if you assign to an ['initialized ] `optional<T&>`, the effect is to
|
||||
[*rebind] to the new object instead of assigning the referee. This is unlike
|
||||
bare C++ references.
|
||||
|
||||
int a = 1 ;
|
||||
int b = 2 ;
|
||||
int& ra = a ;
|
||||
int& rb = b ;
|
||||
optional<int&> ora(ra) ;
|
||||
optional<int&> orb(rb) ;
|
||||
ora = orb ; // 'ora' is rebound to 'b'
|
||||
*ora = 3 ; // Changes value of 'b' (not 'a')
|
||||
assert(a==1);
|
||||
assert(b==3);
|
||||
|
||||
[heading Rationale]
|
||||
|
||||
Rebinding semantics for the assignment of ['initialized ] `optional` references has
|
||||
been chosen to provide [*consistency among initialization states] even at the
|
||||
expense of lack of consistency with the semantics of bare C++ references.
|
||||
It is true that `optional<U>` strives to behave as much as possible as `U`
|
||||
does whenever it is initialized; but in the case when `U` is `T&`, doing so would
|
||||
result in inconsistent behavior w.r.t to the lvalue initialization state.
|
||||
|
||||
Imagine `optional<T&>` forwarding assignment to the referenced object (thus
|
||||
changing the referenced object value but not rebinding), and consider the
|
||||
following code:
|
||||
|
||||
optional<int&> a = get();
|
||||
int x = 1 ;
|
||||
int& rx = x ;
|
||||
optional<int&> b(rx);
|
||||
a = b ;
|
||||
|
||||
What does the assignment do?
|
||||
|
||||
If `a` is ['uninitialized], the answer is clear: it binds to `x` (we now have
|
||||
another reference to `x`).
|
||||
But what if `a` is already ['initialized]? it would change the value of the
|
||||
referenced object (whatever that is); which is inconsistent with the other
|
||||
possible case.
|
||||
|
||||
If `optional<T&>` would assign just like `T&` does, you would never be able to
|
||||
use Optional's assignment without explicitly handling the previous
|
||||
initialization state unless your code is capable of functioning whether
|
||||
after the assignment, `a` aliases the same object as `b` or not.
|
||||
|
||||
That is, you would have to discriminate in order to be consistent.
|
||||
|
||||
If in your code rebinding to another object is not an option, then it is very
|
||||
likely that binding for the first time isn't either. In such case, assignment
|
||||
to an ['uninitialized ] `optional<T&>` shall be prohibited. It is quite possible
|
||||
that in such a scenario it is a precondition that the lvalue must be already
|
||||
initialized. If it isn't, then binding for the first time is OK
|
||||
while rebinding is not which is IMO very unlikely.
|
||||
In such a scenario, you can assign the value itself directly, as in:
|
||||
|
||||
assert(!!opt);
|
||||
*opt=value;
|
||||
|
||||
[endsect]
|
139
doc/15_in_place_factories.qbk
Normal file
139
doc/15_in_place_factories.qbk
Normal file
@ -0,0 +1,139 @@
|
||||
|
||||
[section 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 scheme, 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 family 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 family 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>(123,"hello")) ;
|
||||
}
|
||||
|
||||
The factories are divided in two groups:
|
||||
|
||||
* [_TypedInPlaceFactories]: those which take the target type as a primary
|
||||
template parameter.
|
||||
* [_InPlaceFactories]: those with a template `construct(void*)` member
|
||||
function taking the target type.
|
||||
|
||||
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< class InPlaceFactory >
|
||||
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__
|
||||
|
||||
[endsect]
|
52
doc/16_optional_bool.qbk
Normal file
52
doc/16_optional_bool.qbk
Normal file
@ -0,0 +1,52 @@
|
||||
|
||||
[section 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__— 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, although `optional<>` provides a contextual conversion to `bool` in C++11,
|
||||
this falls back to an implicit conversion on older compilers. 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).
|
||||
|
||||
Third, mixed comparisons with `bool` work differently than similar mixed comparisons between pointers and `bool`, so the results might surprise you:
|
||||
|
||||
optional<bool> oEmpty(none), oTrue(true), oFalse(false);
|
||||
|
||||
if (oEmpty == none); // renders true
|
||||
if (oEmpty == false); // renders false!
|
||||
if (oEmpty == true); // renders false!
|
||||
|
||||
if (oFalse == none); // renders false
|
||||
if (oFalse == false); // renders true!
|
||||
if (oFalse == true); // renders false
|
||||
|
||||
if (oTrue == none); // renders false
|
||||
if (oTrue == false); // renders false
|
||||
if (oTrue == true); // renders true
|
||||
|
||||
In other words, for `optional<>`, the following assertion does not hold:
|
||||
|
||||
assert((opt == false) == (!opt));
|
||||
[endsect]
|
57
doc/17_exception_safety.qbk
Normal file
57
doc/17_exception_safety.qbk
Normal file
@ -0,0 +1,57 @@
|
||||
|
||||
[section Exception Safety Guarantees]
|
||||
|
||||
This library assumes that `T`'s destructor does not throw exceptions. If it does, the behaviour of many operations on `optional<T>` is undefined.
|
||||
|
||||
The following mutating operations never throw exceptions:
|
||||
|
||||
* `optional<T>::operator= ( none_t ) noexcept`
|
||||
* `optional<T>::reset() noexcept`
|
||||
|
||||
In addition, the following constructors and the destructor never throw exceptions:
|
||||
|
||||
* `optional<T>::optional() noexcept`
|
||||
* `optional<T>::optional( none_t ) noexcept`
|
||||
|
||||
|
||||
Regarding the following assignment functions:
|
||||
|
||||
* `optional<T>::operator= ( optional<T> const& )`
|
||||
* `optional<T>::operator= ( T const& )`
|
||||
* `template<class U> optional<T>::operator= ( optional<U> const& )`
|
||||
* `template<class InPlaceFactory> optional<T>::operator= ( InPlaceFactory const& )`
|
||||
* `template<class TypedInPlaceFactory> optional<T>::operator= ( TypedInPlaceFactory const& ) `
|
||||
* `optional<T>::reset( T const& )`
|
||||
|
||||
They forward calls to the corresponding `T`'s constructors or assignments (depending on whether the optional object is initialized or not); so if both `T`'s constructor and the assignment provide strong exception safety guarantee, `optional<T>`'s assignment also provides strong exception safety guarantee; otherwise we only get the basic guarantee. Additionally, if both involved `T`'s constructor and the assignment never throw, `optional<T>`'s assignment also never throws.
|
||||
|
||||
Unless `T`'s constructor or assignment throws, assignments to `optional<T>` do not throw anything else on its own. A throw during assignment never changes the initialization state of any optional object involved:
|
||||
|
||||
|
||||
optional<T> opt1(val1);
|
||||
optional<T> opt2(val2);
|
||||
assert(opt1);
|
||||
assert(opt2);
|
||||
|
||||
try
|
||||
{
|
||||
opt1 = opt2; // throws
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
assert(opt1);
|
||||
assert(opt2);
|
||||
}
|
||||
|
||||
This also applies to move assignments/constructors. However, move operations are made no-throw more often.
|
||||
|
||||
Operation `emplace` provides basic exception safety guarantee. If it throws, the optional object becomes uninitialized regardless of its initial state, and its previous contained value (if any) is destroyed. It doesn't call any assignment or move/copy constructor on `T`.
|
||||
|
||||
[heading Swap]
|
||||
|
||||
Unless `swap` on optional is customized, its primary implementation forwards calls to `T`'s `swap` or move constructor (depending on the initialization state of the optional objects). Thus, if both `T`'s `swap` and move constructor never throw, `swap` on `optional<T>` never throws. similarly, if both `T`'s `swap` and move constructor offer strong guarantee, `swap` on `optional<T>` also offers a strong guarantee.
|
||||
|
||||
In case `swap` on optional is customized, the call to `T`'s move constructor are replaced with the calls to `T`'s default constructor followed by `swap`. (This is more useful on older compilers that do not support move semantics, when one wants to acheive stronger exception safety guarantees.) In this case the exception safety guarantees for `swap` are reliant on the guarantees of `T`'s `swap` and default constructor
|
||||
[endsect]
|
||||
|
||||
|
10
doc/18_type_requirements.qbk
Normal file
10
doc/18_type_requirements.qbk
Normal file
@ -0,0 +1,10 @@
|
||||
|
||||
[section Type requirements]
|
||||
|
||||
At the very minimum for `optional<T>` to work with a minimum interface it is required that `T` has a publicly accessible no-throw destructor. In that case you need to initialize the optional object with function `emplace()` or use [*InPlaceFactories].
|
||||
Additionally, if `T` is `Moveable`, `optional<T>` is also `Moveable` and can be easily initialized from an rvalue of type `T` and be passed by value.
|
||||
Additionally, if `T` is `Copyable`, `optional<T>` is also `Copyable` and can be easily initialized from an lvalue of type `T`.
|
||||
|
||||
`T` [_is not] required to be __SGI_DEFAULT_CONSTRUCTIBLE__.
|
||||
|
||||
[endsect]
|
@ -58,6 +58,8 @@
|
||||
template<class U> optional& operator = ( optional<U> const& rhs ) ; ``[link reference_optional_operator_equal_other_optional __GO_TO__]``
|
||||
|
||||
template<class U> optional& operator = ( optional<U>&& rhs ) ; ``[link reference_optional_operator_move_equal_other_optional __GO_TO__]``
|
||||
|
||||
template<class... Args> void emplace ( Args...&& args ) ; ``[link reference_optional_emplace __GO_TO__]``
|
||||
|
||||
template<class InPlaceFactory> optional& operator = ( InPlaceFactory const& f ) ; ``[link reference_optional_operator_equal_factory __GO_TO__]``
|
||||
|
||||
@ -66,14 +68,19 @@
|
||||
T const& get() const ; ``[link reference_optional_get __GO_TO__]``
|
||||
T& get() ; ``[link reference_optional_get __GO_TO__]``
|
||||
|
||||
// [new in 1.34]
|
||||
T const& get_value_or( T const& default ) const ; ``[link reference_optional_get_value_or_value __GO_TO__]``
|
||||
|
||||
T const* operator ->() const ; ``[link reference_optional_operator_arrow __GO_TO__]``
|
||||
T* operator ->() ; ``[link reference_optional_operator_arrow __GO_TO__]``
|
||||
|
||||
T const& operator *() const ; ``[link reference_optional_get __GO_TO__]``
|
||||
T& operator *() ; ``[link reference_optional_get __GO_TO__]``
|
||||
T const& operator *() const& ; ``[link reference_optional_operator_asterisk __GO_TO__]``
|
||||
T& operator *() &; ``[link reference_optional_operator_asterisk __GO_TO__]``
|
||||
T&& operator *() &&; ``[link reference_optional_operator_asterisk __GO_TO__]``
|
||||
|
||||
T const& value() const& ; ``[link reference_optional_value __GO_TO__]``
|
||||
T& value() & ; ``[link reference_optional_value __GO_TO__]``
|
||||
T&& value() && ; ``[link reference_optional_value __GO_TO__]``
|
||||
|
||||
template<class U> T value_or( U && v ) const& ; ``[link reference_optional_value_or __GO_TO__]``
|
||||
template<class U> T value_or( U && v ) && ; ``[link reference_optional_value_or __GO_TO__]``
|
||||
|
||||
T const* get_ptr() const ; ``[link reference_optional_get_ptr __GO_TO__]``
|
||||
T* get_ptr() ; ``[link reference_optional_get_ptr __GO_TO__]``
|
||||
@ -93,6 +100,8 @@
|
||||
// (deprecated)
|
||||
bool is_initialized() const ; ``[link reference_optional_is_initialized __GO_TO__]``
|
||||
|
||||
// (deprecated)
|
||||
T const& get_value_or( T const& default ) const ; ``[link reference_optional_get_value_or_value __GO_TO__]``
|
||||
};
|
||||
|
||||
template<class T> inline bool operator == ( optional<T> const& x, optional<T> const& y ) ; ``[link reference_operator_compare_equal_optional_optional __GO_TO__]``
|
||||
@ -111,13 +120,10 @@
|
||||
|
||||
template<class T> inline bool operator != ( optional<T> const& x, none_t ) noexcept ; ``[link reference_operator_compare_not_equal_optional_none __GO_TO__]``
|
||||
|
||||
// [new in 1.34]
|
||||
template<class T> inline optional<T> make_optional ( T const& v ) ; ``[link reference_make_optional_value __GO_TO__]``
|
||||
|
||||
// [new in 1.34]
|
||||
template<class T> inline optional<T> make_optional ( bool condition, T const& v ) ; ``[link reference_make_optional_bool_value __GO_TO__]``
|
||||
|
||||
// [new in 1.34]
|
||||
template<class T> inline T const& get_optional_value_or ( optional<T> const& opt, T const& default ) ; ``[link reference_optional_get_value_or_value __GO_TO__]``
|
||||
|
||||
template<class T> inline T const& get ( optional<T> const& opt ) ; ``[link reference_optional_get __GO_TO__]``
|
||||
@ -464,7 +470,7 @@ 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 [link boost_optional.in_place_factories In-Place Factories]
|
||||
* [*Notes:] See [link boost_optional.tutorial.in_place_factories 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.
|
||||
@ -527,7 +533,7 @@ __SPACE__
|
||||
* [*Postconditions: ] `*this` is initialized and it references the same
|
||||
object referenced by `rhs`.
|
||||
* [*Notes:] If `*this` was initialized, it is ['rebound] to the new object.
|
||||
See [link boost_optional.rebinding_semantics_for_assignment_of_optional_references here] for details on this behavior.
|
||||
See [link boost_optional.tutorial.rebinding_semantics_for_assignment_of_optional_references here] for details on this behavior.
|
||||
* [*Example:]
|
||||
``
|
||||
int a = 1 ;
|
||||
@ -622,7 +628,7 @@ __SPACE__
|
||||
references the same object referenced by `*rhs`; otherwise, `*this` is
|
||||
uninitialized (and references no object).
|
||||
* [*Notes:] If `*this` was initialized and so is `*rhs`, `*this` is ['rebound] to
|
||||
the new object. See [link boost_optional.rebinding_semantics_for_assignment_of_optional_references here] for details on this behavior.
|
||||
the new object. See [link boost_optional.tutorial.rebinding_semantics_for_assignment_of_optional_references here] for details on this behavior.
|
||||
* [*Example:]
|
||||
``
|
||||
int a = 1 ;
|
||||
@ -745,6 +751,21 @@ assert ( *opt1 == static_cast<U>(v) ) ;
|
||||
|
||||
__SPACE__
|
||||
|
||||
[#reference_optional_emplace]
|
||||
|
||||
[: `template<class... Args> void optional<T` ['(not a ref)]`>::emplace( Args...&& args );`]
|
||||
|
||||
* [*Requires:] The compiler supports rvalue references and variadic templates.
|
||||
* [*Effect:] If `*this` is initialized calls `*this = none`.
|
||||
Then initializes in-place the contained value as if direct-initializing an object
|
||||
of type `T` with `std::forward<Args>(args)...`.
|
||||
* [*Postconditions: ] `*this` is [_initialized].
|
||||
* [*Throws:] Whatever the selected `T`'s constructor throws.
|
||||
* [*Notes:] `T` need not be `MoveConstructible` or `MoveAssignable`.
|
||||
* [*Exception Safety:] If an exception is thrown during the initialization of `T`, `*this` is ['uninitialized].
|
||||
|
||||
__SPACE__
|
||||
|
||||
[#reference_optional_operator_equal_factory]
|
||||
|
||||
[: `template<InPlaceFactory> optional<T>& optional<T` ['(not a ref)]`>::operator=( InPlaceFactory const& f );`]
|
||||
@ -755,7 +776,7 @@ 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 [link boost_optional.in_place_factories In-Place Factories]
|
||||
* [*Notes:] See [link boost_optional.tutorial.in_place_factories In-Place Factories]
|
||||
* [*Exception Safety:] Exceptions can only be thrown during the call to
|
||||
the `T` constructor used by the factory; in that case, the `optional` object
|
||||
will be reset to be ['uninitialized].
|
||||
@ -772,14 +793,12 @@ __SPACE__
|
||||
[#reference_optional_reset]
|
||||
|
||||
[: `void optional<T>::reset() noexcept ;`]
|
||||
* [*Deprecated:] Same as `operator=( detail::none_t );`
|
||||
* [*Deprecated:] Same as `operator=( none_t );`
|
||||
|
||||
__SPACE__
|
||||
|
||||
[#reference_optional_get]
|
||||
|
||||
[: `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() ;`]
|
||||
|
||||
@ -790,6 +809,32 @@ __SPACE__
|
||||
* [*Returns:] A reference to the contained value
|
||||
* [*Throws:] Nothing.
|
||||
* [*Notes:] The requirement is asserted via `BOOST_ASSERT()`.
|
||||
|
||||
__SPACE__
|
||||
|
||||
[: `T const& optional<T&>::get() const ;`]
|
||||
[: `T& optional<T&>::get() ;`]
|
||||
|
||||
[: `inline T const& get ( optional<T&> const& ) ;`]
|
||||
[: `inline T& get ( optional<T&> &) ;`]
|
||||
|
||||
* [*Requires: ] `*this` is initialized
|
||||
* [*Returns:] [_The] reference contained.
|
||||
* [*Throws:] Nothing.
|
||||
* [*Notes:] The requirement is asserted via `BOOST_ASSERT()`.
|
||||
|
||||
__SPACE__
|
||||
|
||||
[#reference_optional_operator_asterisk]
|
||||
|
||||
[: `T const& optional<T` ['(not a ref)]`>::operator*() const& ;`]
|
||||
[: `T& optional<T` ['(not a ref)]`>::operator*() &;`]
|
||||
[: `T&& optional<T` ['(not a ref)]`>::operator*() &&;`]
|
||||
|
||||
* [*Requires:] `*this` is initialized
|
||||
* [*Returns:] A reference to the contained value
|
||||
* [*Throws:] Nothing.
|
||||
* [*Notes:] The requirement is asserted via `BOOST_ASSERT()`. On compilers that do not support ref-qualifiers on member functions these three overloads are replaced with the classical two: a `const` and non-`const` member functions.
|
||||
* [*Example:]
|
||||
``
|
||||
T v ;
|
||||
@ -803,6 +848,65 @@ assert ( *opt == w ) ;
|
||||
|
||||
__SPACE__
|
||||
|
||||
[: `T const& optional<T&>::operator*() const& ;`]
|
||||
[: `T & optional<T&>::operator*() & ;`]
|
||||
[: `T & optional<T&>::operator*() && ;`]
|
||||
|
||||
* [*Requires: ] `*this` is initialized
|
||||
* [*Returns:] [_The] reference contained.
|
||||
* [*Throws:] Nothing.
|
||||
* [*Notes:] The requirement is asserted via `BOOST_ASSERT()`. On compilers that do not support ref-qualifiers on member functions these three overloads are replaced with the classical two: a `const` and non-`const` member functions.
|
||||
* [*Example:]
|
||||
``
|
||||
T v ;
|
||||
T& vref = v ;
|
||||
optional<T&> opt ( vref );
|
||||
T const& vref2 = *opt;
|
||||
assert ( vref2 == v ) ;
|
||||
++ v ;
|
||||
assert ( *opt == v ) ;
|
||||
``
|
||||
|
||||
__SPACE__
|
||||
|
||||
[#reference_optional_value]
|
||||
|
||||
[: `T const& optional<T>::value() const& ;`]
|
||||
[: `T& optional<T>::value() & ;`]
|
||||
[: `T&& optional<T>::value() && ;`]
|
||||
|
||||
* [*Returns:] A reference to the contained value, if `*this` is initialized.
|
||||
* [*Throws:] An instance of `bad_optional_access`, if `*this` is not initialized.
|
||||
* [*Notes:] On compilers that do not support ref-qualifiers on member functions these three overloads are replaced with the classical two: a `const` and non-`const` member functions.
|
||||
* [*Example:]
|
||||
``
|
||||
T v ;
|
||||
optional<T> o0, o1 ( v );
|
||||
assert ( o1.value() == v );
|
||||
|
||||
try {
|
||||
o0.value(); // throws
|
||||
assert ( false );
|
||||
}
|
||||
catch(bad_optional_access&) {
|
||||
assert ( true );
|
||||
}
|
||||
``
|
||||
__SPACE__
|
||||
|
||||
|
||||
[#reference_optional_value_or]
|
||||
|
||||
[: `template<class U> T optional<T>::value_or(U && v) const& ;`]
|
||||
[: `template<class U> T optional<T>::value_or(U && v) && ;`]
|
||||
|
||||
* [*Requires:] `T` is CopyConstructible.
|
||||
* [*Returns:] First overload: `bool(*this) ? **this : static_cast<T>(forward<U>(v))`. second overload: `bool(*this) ? std::move(**this) : static_cast<T>(forward<U>(v))`.
|
||||
* [*Throws:] Any exception thrown by the selected constructor of `T`.
|
||||
* [*Notes:] On compilers that do not support ref-qualifiers on member functions these three overloads are replaced with the classical two: a `const` and non-`const` member functions. On compilers without rvalue reference support the type of `v` becomes `U const&`.
|
||||
|
||||
__SPACE__
|
||||
|
||||
[#reference_optional_get_value_or_value]
|
||||
|
||||
[: `T const& optional<T` ['(not a ref)]`>::get_value_or( T const& default) const ;`]
|
||||
@ -811,6 +915,7 @@ __SPACE__
|
||||
[: `inline T const& get_optional_value_or ( optional<T` ['(not a ref)]`> const& o, T const& default ) ;`]
|
||||
[: `inline T& get_optional_value_or ( optional<T` ['(not a ref)]`>& o, T& default ) ;`]
|
||||
|
||||
* [*Deprecated:] Use `value_or()` instead.
|
||||
* [*Returns:] A reference to the contained value, if any, or `default`.
|
||||
* [*Throws:] Nothing.
|
||||
* [*Example:]
|
||||
@ -826,30 +931,6 @@ assert ( u == v ) ;
|
||||
assert ( u != z ) ;
|
||||
``
|
||||
|
||||
__SPACE__
|
||||
|
||||
[: `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&> &) ;`]
|
||||
|
||||
* [*Requires: ] `*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 ) ;
|
||||
``
|
||||
|
||||
__SPACE__
|
||||
|
@ -11,8 +11,22 @@
|
||||
|
||||
[section Dependencies and Portability]
|
||||
|
||||
The implementation uses `type_traits/alignment_of.hpp` and
|
||||
`type_traits/type_with_alignment.hpp`
|
||||
[section Dependencies]
|
||||
The implementation uses the following other Boost modules:
|
||||
|
||||
# assert
|
||||
# config
|
||||
# core
|
||||
# detail
|
||||
# move
|
||||
# mpl
|
||||
# static_assert
|
||||
# throw_exception
|
||||
# type_traits
|
||||
# utility
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
[section Optional Reference Binding]
|
||||
|
@ -17,7 +17,7 @@ path-constant images : html ;
|
||||
|
||||
xml optional
|
||||
:
|
||||
optional.qbk
|
||||
00_optional.qbk
|
||||
;
|
||||
|
||||
boostbook standalone
|
||||
@ -25,9 +25,11 @@ boostbook standalone
|
||||
optional
|
||||
:
|
||||
<xsl:param>boost.root=../../../..
|
||||
<xsl:param>toc.max.depth=2
|
||||
<xsl:param>chapter.autolabel=0
|
||||
<xsl:param>chunk.section.depth=8
|
||||
<xsl:param>toc.section.depth=2
|
||||
<xsl:param>chunk.section.depth=1
|
||||
<xsl:param>toc.max.depth=2
|
||||
<xsl:param>generate.section.toc.level=1
|
||||
<format>pdf:<xsl:param>img.src.path=$(images)/
|
||||
<format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/libs/optional/doc/html
|
||||
;
|
||||
|
102
doc/examples.qbk
102
doc/examples.qbk
@ -1,102 +0,0 @@
|
||||
[/
|
||||
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)
|
||||
]
|
||||
|
||||
|
||||
[section Examples]
|
||||
|
||||
[section 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);
|
||||
}
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Optional local variables]
|
||||
|
||||
optional<string> name ;
|
||||
if ( database.open() )
|
||||
{
|
||||
name = database.lookup(employer_name) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( can_ask_user )
|
||||
name = user.ask(employer_name) ;
|
||||
}
|
||||
|
||||
if ( name )
|
||||
print(*name);
|
||||
else print("employer's name not found!");
|
||||
|
||||
[endsect]
|
||||
|
||||
[section 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 = 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 ;
|
||||
|
||||
};
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Bypassing expensive unnecessary default construction]
|
||||
|
||||
class ExpensiveCtor { ... } ;
|
||||
class Fred
|
||||
{
|
||||
Fred() : mLargeVector(10000) {}
|
||||
|
||||
std::vector< optional<ExpensiveCtor> > mLargeVector ;
|
||||
} ;
|
||||
|
||||
[endsect]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||
<link rel="home" href="../index.html" title="Chapter 1. Boost.Optional">
|
||||
<link rel="up" href="../index.html" title="Chapter 1. Boost.Optional">
|
||||
<link rel="prev" href="in_place_factories.html" title="In-Place Factories">
|
||||
<link rel="prev" href="detailed_semantics.html" title="Detailed Semantics">
|
||||
<link rel="next" href="exception_safety_guarantees.html" title="Exception Safety Guarantees">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
@ -20,7 +20,7 @@
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="in_place_factories.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="exception_safety_guarantees.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
<a accesskey="p" href="detailed_semantics.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="exception_safety_guarantees.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
@ -102,7 +102,7 @@
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="in_place_factories.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="exception_safety_guarantees.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
<a accesskey="p" href="detailed_semantics.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="exception_safety_guarantees.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -4,9 +4,9 @@
|
||||
<title>Acknowledgments</title>
|
||||
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||
<link rel="home" href="../index.html" title="Chapter 1. Boost.Optional">
|
||||
<link rel="up" href="../index.html" title="Chapter 1. Boost.Optional">
|
||||
<link rel="prev" href="dependencies_and_portability.html" title="Dependencies and Portability">
|
||||
<link rel="home" href="../index.html" title="Boost.Optional">
|
||||
<link rel="up" href="../index.html" title="Boost.Optional">
|
||||
<link rel="prev" href="dependencies_and_portability/optional_reference_binding.html" title="Optional Reference Binding">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
@ -19,7 +19,7 @@
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="dependencies_and_portability.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a>
|
||||
<a accesskey="p" href="dependencies_and_portability/optional_reference_binding.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
@ -119,7 +119,7 @@
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="dependencies_and_portability.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a>
|
||||
<a accesskey="p" href="dependencies_and_portability/optional_reference_binding.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -4,10 +4,10 @@
|
||||
<title>Dependencies and Portability</title>
|
||||
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||
<link rel="home" href="../index.html" title="Chapter 1. Boost.Optional">
|
||||
<link rel="up" href="../index.html" title="Chapter 1. Boost.Optional">
|
||||
<link rel="prev" href="type_requirements.html" title="Type requirements">
|
||||
<link rel="next" href="acknowledgments.html" title="Acknowledgments">
|
||||
<link rel="home" href="../index.html" title="Boost.Optional">
|
||||
<link rel="up" href="../index.html" title="Boost.Optional">
|
||||
<link rel="prev" href="reference/detailed_semantics.html" title="Detailed Semantics">
|
||||
<link rel="next" href="dependencies_and_portability/optional_reference_binding.html" title="Optional Reference Binding">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
@ -20,80 +20,57 @@
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="type_requirements.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="acknowledgments.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
<a accesskey="p" href="reference/detailed_semantics.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="dependencies_and_portability/optional_reference_binding.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="boost_optional.dependencies_and_portability"></a><a class="link" href="dependencies_and_portability.html" title="Dependencies and Portability">Dependencies
|
||||
and Portability</a>
|
||||
</h2></div></div></div>
|
||||
<div class="toc"><dl class="toc"><dt><span class="section"><a href="dependencies_and_portability.html#boost_optional.dependencies_and_portability.optional_reference_binding">Optional
|
||||
Reference Binding</a></span></dt></dl></div>
|
||||
<p>
|
||||
The implementation uses <code class="computeroutput"><span class="identifier">type_traits</span><span class="special">/</span><span class="identifier">alignment_of</span><span class="special">.</span><span class="identifier">hpp</span></code> and
|
||||
<code class="computeroutput"><span class="identifier">type_traits</span><span class="special">/</span><span class="identifier">type_with_alignment</span><span class="special">.</span><span class="identifier">hpp</span></code>
|
||||
</p>
|
||||
<div class="toc"><dl class="toc">
|
||||
<dt><span class="section"><a href="dependencies_and_portability.html#boost_optional.dependencies_and_portability.dependencies">Dependencies</a></span></dt>
|
||||
<dt><span class="section"><a href="dependencies_and_portability/optional_reference_binding.html">Optional
|
||||
Reference Binding</a></span></dt>
|
||||
</dl></div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_optional.dependencies_and_portability.optional_reference_binding"></a><a class="link" href="dependencies_and_portability.html#boost_optional.dependencies_and_portability.optional_reference_binding" title="Optional Reference Binding">Optional
|
||||
Reference Binding</a>
|
||||
<a name="boost_optional.dependencies_and_portability.dependencies"></a><a class="link" href="dependencies_and_portability.html#boost_optional.dependencies_and_portability.dependencies" title="Dependencies">Dependencies</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
On compilers that do not conform to Standard C++ rules of reference binding,
|
||||
operations on optional references might give adverse results: rather than
|
||||
binding a reference to a designated object they may create an unexpected
|
||||
temporary and bind to it. Compilers known to have these deficiencies include
|
||||
GCC versions 4.2, 4.3, 4.4, 4.5; QCC 4.4.2; MSVC versions 8.0, 9.0, 10.0,
|
||||
11.0, 12.0. On these compilers prefer using direct-initialization and copy
|
||||
assignment of optional references to copy-initialization and assignment from
|
||||
<code class="computeroutput"><span class="identifier">T</span><span class="special">&</span></code>:
|
||||
The implementation uses the following other Boost modules:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">const</span> <span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="identifier">optional</span><span class="special"><</span><span class="keyword">const</span> <span class="keyword">int</span><span class="special">&></span> <span class="identifier">or1</span><span class="special">;</span>
|
||||
<span class="identifier">optional</span><span class="special"><</span><span class="keyword">const</span> <span class="keyword">int</span><span class="special">&></span> <span class="identifier">or2</span> <span class="special">=</span> <span class="identifier">i</span><span class="special">;</span> <span class="comment">// not portable</span>
|
||||
<span class="identifier">or1</span> <span class="special">=</span> <span class="identifier">i</span><span class="special">;</span> <span class="comment">// not portable</span>
|
||||
|
||||
<span class="identifier">optional</span><span class="special"><</span><span class="keyword">const</span> <span class="keyword">int</span><span class="special">&></span> <span class="identifier">or3</span><span class="special">(</span><span class="identifier">i</span><span class="special">);</span> <span class="comment">// portable</span>
|
||||
<span class="identifier">or1</span> <span class="special">=</span> <span class="identifier">optional</span><span class="special"><</span><span class="keyword">const</span> <span class="keyword">int</span><span class="special">&>(</span><span class="identifier">i</span><span class="special">);</span> <span class="comment">// portable</span>
|
||||
</pre>
|
||||
<p>
|
||||
In order to check if your compiler correctly implements reference binding
|
||||
use this test program.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span>
|
||||
|
||||
<span class="keyword">const</span> <span class="keyword">int</span> <span class="identifier">global_i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
|
||||
|
||||
<span class="keyword">struct</span> <span class="identifier">TestingReferenceBinding</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">TestingReferenceBinding</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">int</span><span class="special">&</span> <span class="identifier">ii</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">assert</span><span class="special">(&</span><span class="identifier">ii</span> <span class="special">==</span> <span class="special">&</span><span class="identifier">global_i</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">=(</span><span class="keyword">const</span> <span class="keyword">int</span><span class="special">&</span> <span class="identifier">ii</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">assert</span><span class="special">(&</span><span class="identifier">ii</span> <span class="special">==</span> <span class="special">&</span><span class="identifier">global_i</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">=(</span><span class="keyword">int</span><span class="special">&&)</span> <span class="comment">// remove this if your compiler doesn't have rvalue refs</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">assert</span><span class="special">(</span><span class="keyword">false</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
<span class="special">};</span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">const</span> <span class="keyword">int</span><span class="special">&</span> <span class="identifier">iref</span> <span class="special">=</span> <span class="identifier">global_i</span><span class="special">;</span>
|
||||
<span class="identifier">assert</span><span class="special">(&</span><span class="identifier">iref</span> <span class="special">==</span> <span class="special">&</span><span class="identifier">global_i</span><span class="special">);</span>
|
||||
|
||||
<span class="identifier">TestingReferenceBinding</span> <span class="identifier">ttt</span> <span class="special">=</span> <span class="identifier">global_i</span><span class="special">;</span>
|
||||
<span class="identifier">ttt</span> <span class="special">=</span> <span class="identifier">global_i</span><span class="special">;</span>
|
||||
|
||||
<span class="identifier">TestingReferenceBinding</span> <span class="identifier">ttt2</span> <span class="special">=</span> <span class="identifier">iref</span><span class="special">;</span>
|
||||
<span class="identifier">ttt2</span> <span class="special">=</span> <span class="identifier">iref</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<div class="orderedlist"><ol class="orderedlist" type="1">
|
||||
<li class="listitem">
|
||||
assert
|
||||
</li>
|
||||
<li class="listitem">
|
||||
config
|
||||
</li>
|
||||
<li class="listitem">
|
||||
core
|
||||
</li>
|
||||
<li class="listitem">
|
||||
detail
|
||||
</li>
|
||||
<li class="listitem">
|
||||
move
|
||||
</li>
|
||||
<li class="listitem">
|
||||
mpl
|
||||
</li>
|
||||
<li class="listitem">
|
||||
static_assert
|
||||
</li>
|
||||
<li class="listitem">
|
||||
throw_exception
|
||||
</li>
|
||||
<li class="listitem">
|
||||
type_traits
|
||||
</li>
|
||||
<li class="listitem">
|
||||
utility
|
||||
</li>
|
||||
</ol></div>
|
||||
</div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
@ -106,7 +83,7 @@
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="type_requirements.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="acknowledgments.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
<a accesskey="p" href="reference/detailed_semantics.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="dependencies_and_portability/optional_reference_binding.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -0,0 +1,100 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Optional Reference Binding</title>
|
||||
<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||
<link rel="home" href="../../index.html" title="Boost.Optional">
|
||||
<link rel="up" href="../dependencies_and_portability.html" title="Dependencies and Portability">
|
||||
<link rel="prev" href="../dependencies_and_portability.html" title="Dependencies and Portability">
|
||||
<link rel="next" href="../acknowledgments.html" title="Acknowledgments">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="../dependencies_and_portability.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../dependencies_and_portability.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../acknowledgments.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_optional.dependencies_and_portability.optional_reference_binding"></a><a class="link" href="optional_reference_binding.html" title="Optional Reference Binding">Optional
|
||||
Reference Binding</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
On compilers that do not conform to Standard C++ rules of reference binding,
|
||||
operations on optional references might give adverse results: rather than
|
||||
binding a reference to a designated object they may create an unexpected
|
||||
temporary and bind to it. Compilers known to have these deficiencies include
|
||||
GCC versions 4.2, 4.3, 4.4, 4.5; QCC 4.4.2; MSVC versions 8.0, 9.0, 10.0,
|
||||
11.0, 12.0. On these compilers prefer using direct-initialization and copy
|
||||
assignment of optional references to copy-initialization and assignment from
|
||||
<code class="computeroutput"><span class="identifier">T</span><span class="special">&</span></code>:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">const</span> <span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
|
||||
<span class="identifier">optional</span><span class="special"><</span><span class="keyword">const</span> <span class="keyword">int</span><span class="special">&></span> <span class="identifier">or1</span><span class="special">;</span>
|
||||
<span class="identifier">optional</span><span class="special"><</span><span class="keyword">const</span> <span class="keyword">int</span><span class="special">&></span> <span class="identifier">or2</span> <span class="special">=</span> <span class="identifier">i</span><span class="special">;</span> <span class="comment">// not portable</span>
|
||||
<span class="identifier">or1</span> <span class="special">=</span> <span class="identifier">i</span><span class="special">;</span> <span class="comment">// not portable</span>
|
||||
|
||||
<span class="identifier">optional</span><span class="special"><</span><span class="keyword">const</span> <span class="keyword">int</span><span class="special">&></span> <span class="identifier">or3</span><span class="special">(</span><span class="identifier">i</span><span class="special">);</span> <span class="comment">// portable</span>
|
||||
<span class="identifier">or1</span> <span class="special">=</span> <span class="identifier">optional</span><span class="special"><</span><span class="keyword">const</span> <span class="keyword">int</span><span class="special">&>(</span><span class="identifier">i</span><span class="special">);</span> <span class="comment">// portable</span>
|
||||
</pre>
|
||||
<p>
|
||||
In order to check if your compiler correctly implements reference binding
|
||||
use this test program.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">cassert</span><span class="special">></span>
|
||||
|
||||
<span class="keyword">const</span> <span class="keyword">int</span> <span class="identifier">global_i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
|
||||
|
||||
<span class="keyword">struct</span> <span class="identifier">TestingReferenceBinding</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">TestingReferenceBinding</span><span class="special">(</span><span class="keyword">const</span> <span class="keyword">int</span><span class="special">&</span> <span class="identifier">ii</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">assert</span><span class="special">(&</span><span class="identifier">ii</span> <span class="special">==</span> <span class="special">&</span><span class="identifier">global_i</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">=(</span><span class="keyword">const</span> <span class="keyword">int</span><span class="special">&</span> <span class="identifier">ii</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">assert</span><span class="special">(&</span><span class="identifier">ii</span> <span class="special">==</span> <span class="special">&</span><span class="identifier">global_i</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
|
||||
<span class="keyword">void</span> <span class="keyword">operator</span><span class="special">=(</span><span class="keyword">int</span><span class="special">&&)</span> <span class="comment">// remove this if your compiler doesn't have rvalue refs</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">assert</span><span class="special">(</span><span class="keyword">false</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
<span class="special">};</span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">const</span> <span class="keyword">int</span><span class="special">&</span> <span class="identifier">iref</span> <span class="special">=</span> <span class="identifier">global_i</span><span class="special">;</span>
|
||||
<span class="identifier">assert</span><span class="special">(&</span><span class="identifier">iref</span> <span class="special">==</span> <span class="special">&</span><span class="identifier">global_i</span><span class="special">);</span>
|
||||
|
||||
<span class="identifier">TestingReferenceBinding</span> <span class="identifier">ttt</span> <span class="special">=</span> <span class="identifier">global_i</span><span class="special">;</span>
|
||||
<span class="identifier">ttt</span> <span class="special">=</span> <span class="identifier">global_i</span><span class="special">;</span>
|
||||
|
||||
<span class="identifier">TestingReferenceBinding</span> <span class="identifier">ttt2</span> <span class="special">=</span> <span class="identifier">iref</span><span class="special">;</span>
|
||||
<span class="identifier">ttt2</span> <span class="special">=</span> <span class="identifier">iref</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014 Andrzej Krzemieński<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
</div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="../dependencies_and_portability.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../dependencies_and_portability.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../acknowledgments.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -7,7 +7,7 @@
|
||||
<link rel="home" href="../index.html" title="Chapter 1. Boost.Optional">
|
||||
<link rel="up" href="../index.html" title="Chapter 1. Boost.Optional">
|
||||
<link rel="prev" href="synopsis.html" title="Synopsis">
|
||||
<link rel="next" href="examples.html" title="Examples">
|
||||
<link rel="next" href="dependencies_and_portability.html" title="Dependencies and Portability">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
@ -20,7 +20,7 @@
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="synopsis.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="examples.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
<a accesskey="p" href="synopsis.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="dependencies_and_portability.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
@ -606,7 +606,7 @@
|
||||
constructor called by the factory throws.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Notes:</strong></span> See <a class="link" href="in_place_factories.html" title="In-Place Factories">In-Place
|
||||
<span class="bold"><strong>Notes:</strong></span> See <a class="link" href="tutorial/in_place_factories.html" title="In-Place Factories">In-Place
|
||||
Factories</a>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
@ -712,7 +712,7 @@
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Notes:</strong></span> If <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> was initialized, it is <span class="emphasis"><em>rebound</em></span>
|
||||
to the new object. See <a class="link" href="rebinding_semantics_for_assignment_of_optional_references.html" title="Rebinding semantics for assignment of optional references">here</a>
|
||||
to the new object. See <a class="link" href="tutorial/rebinding_semantics_for_assignment_of_optional_references.html" title="Rebinding semantics for assignment of optional references">here</a>
|
||||
for details on this behavior.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
@ -872,7 +872,7 @@
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Notes:</strong></span> If <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> was initialized and so is <code class="computeroutput"><span class="special">*</span><span class="identifier">rhs</span></code>,
|
||||
<code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
|
||||
is <span class="emphasis"><em>rebound</em></span> to the new object. See <a class="link" href="rebinding_semantics_for_assignment_of_optional_references.html" title="Rebinding semantics for assignment of optional references">here</a>
|
||||
is <span class="emphasis"><em>rebound</em></span> to the new object. See <a class="link" href="tutorial/rebinding_semantics_for_assignment_of_optional_references.html" title="Rebinding semantics for assignment of optional references">here</a>
|
||||
for details on this behavior.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
@ -1080,6 +1080,42 @@
|
||||
</pre>
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
<span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span>
|
||||
</p>
|
||||
<a name="reference_optional_emplace"></a><div class="blockquote"><blockquote class="blockquote"><p>
|
||||
<code class="computeroutput"><span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span><span class="special">...</span> <span class="identifier">Args</span><span class="special">></span> <span class="keyword">void</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span></code>
|
||||
<span class="emphasis"><em>(not a ref)</em></span><code class="computeroutput"><span class="special">>::</span><span class="identifier">emplace</span><span class="special">(</span> <span class="identifier">Args</span><span class="special">...&&</span>
|
||||
<span class="identifier">args</span> <span class="special">);</span></code>
|
||||
</p></blockquote></div>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Requires:</strong></span> The compiler supports rvalue
|
||||
references and variadic templates.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Effect:</strong></span> If <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is initialized calls <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span> <span class="special">=</span>
|
||||
<span class="identifier">none</span></code>. Then initializes in-place
|
||||
the contained value as if direct-initializing an object of type <code class="computeroutput"><span class="identifier">T</span></code> with <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">forward</span><span class="special"><</span><span class="identifier">Args</span><span class="special">>(</span><span class="identifier">args</span><span class="special">)...</span></code>.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Postconditions: </strong></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is <span class="underline">initialized</span>.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Throws:</strong></span> Whatever the selected <code class="computeroutput"><span class="identifier">T</span></code>'s constructor throws.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Notes:</strong></span> <code class="computeroutput"><span class="identifier">T</span></code>
|
||||
need not be <code class="computeroutput"><span class="identifier">MoveConstructible</span></code>
|
||||
or <code class="computeroutput"><span class="identifier">MoveAssignable</span></code>.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Exception Safety:</strong></span> If an exception is thrown
|
||||
during the initialization of <code class="computeroutput"><span class="identifier">T</span></code>,
|
||||
<code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
|
||||
is <span class="emphasis"><em>uninitialized</em></span>.
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
<span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span>
|
||||
</p>
|
||||
@ -1111,7 +1147,7 @@
|
||||
constructor called by the factory throws.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Notes:</strong></span> See <a class="link" href="in_place_factories.html" title="In-Place Factories">In-Place
|
||||
<span class="bold"><strong>Notes:</strong></span> See <a class="link" href="tutorial/in_place_factories.html" title="In-Place Factories">In-Place
|
||||
Factories</a>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
@ -1141,20 +1177,12 @@
|
||||
<code class="computeroutput"><span class="keyword">void</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">reset</span><span class="special">()</span> <span class="keyword">noexcept</span> <span class="special">;</span></code>
|
||||
</p></blockquote></div>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||||
<span class="bold"><strong>Deprecated:</strong></span> Same as <code class="computeroutput"><span class="keyword">operator</span><span class="special">=(</span> <span class="identifier">detail</span><span class="special">::</span><span class="identifier">none_t</span> <span class="special">);</span></code>
|
||||
<span class="bold"><strong>Deprecated:</strong></span> Same as <code class="computeroutput"><span class="keyword">operator</span><span class="special">=(</span> <span class="identifier">none_t</span> <span class="special">);</span></code>
|
||||
</li></ul></div>
|
||||
<p>
|
||||
<span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span>
|
||||
</p>
|
||||
<a name="reference_optional_get"></a><div class="blockquote"><blockquote class="blockquote"><p>
|
||||
<code class="computeroutput"><span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span></code>
|
||||
<span class="emphasis"><em>(not a ref)</em></span><code class="computeroutput"><span class="special">>::</span><span class="keyword">operator</span><span class="special">*()</span> <span class="keyword">const</span> <span class="special">;</span></code>
|
||||
</p></blockquote></div>
|
||||
<div class="blockquote"><blockquote class="blockquote"><p>
|
||||
<code class="computeroutput"><span class="identifier">T</span><span class="special">&</span>
|
||||
<span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span></code> <span class="emphasis"><em>(not a ref)</em></span><code class="computeroutput"><span class="special">>::</span><span class="keyword">operator</span><span class="special">*();</span></code>
|
||||
</p></blockquote></div>
|
||||
<div class="blockquote"><blockquote class="blockquote"><p>
|
||||
<code class="computeroutput"><span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span></code>
|
||||
<span class="emphasis"><em>(not a ref)</em></span><code class="computeroutput"><span class="special">>::</span><span class="identifier">get</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span></code>
|
||||
</p></blockquote></div>
|
||||
@ -1188,76 +1216,10 @@
|
||||
<span class="bold"><strong>Notes:</strong></span> The requirement is asserted via
|
||||
<code class="computeroutput"><span class="identifier">BOOST_ASSERT</span><span class="special">()</span></code>.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Example:</strong></span>
|
||||
<pre class="programlisting"><span class="identifier">T</span> <span class="identifier">v</span> <span class="special">;</span>
|
||||
<span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="identifier">opt</span> <span class="special">(</span> <span class="identifier">v</span> <span class="special">);</span>
|
||||
<span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">u</span> <span class="special">=</span> <span class="special">*</span><span class="identifier">opt</span><span class="special">;</span>
|
||||
<span class="identifier">assert</span> <span class="special">(</span> <span class="identifier">u</span> <span class="special">==</span> <span class="identifier">v</span> <span class="special">)</span> <span class="special">;</span>
|
||||
<span class="identifier">T</span> <span class="identifier">w</span> <span class="special">;</span>
|
||||
<span class="special">*</span><span class="identifier">opt</span> <span class="special">=</span> <span class="identifier">w</span> <span class="special">;</span>
|
||||
<span class="identifier">assert</span> <span class="special">(</span> <span class="special">*</span><span class="identifier">opt</span> <span class="special">==</span> <span class="identifier">w</span> <span class="special">)</span> <span class="special">;</span>
|
||||
</pre>
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
<span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span>
|
||||
</p>
|
||||
<a name="reference_optional_get_value_or_value"></a><div class="blockquote"><blockquote class="blockquote"><p>
|
||||
<code class="computeroutput"><span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span></code>
|
||||
<span class="emphasis"><em>(not a ref)</em></span><code class="computeroutput"><span class="special">>::</span><span class="identifier">get_value_or</span><span class="special">(</span>
|
||||
<span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="keyword">default</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span></code>
|
||||
</p></blockquote></div>
|
||||
<div class="blockquote"><blockquote class="blockquote"><p>
|
||||
<code class="computeroutput"><span class="identifier">T</span><span class="special">&</span>
|
||||
<span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span></code> <span class="emphasis"><em>(not a ref)</em></span><code class="computeroutput"><span class="special">>::</span><span class="identifier">get_value_or</span><span class="special">(</span> <span class="identifier">T</span><span class="special">&</span>
|
||||
<span class="keyword">default</span> <span class="special">)</span>
|
||||
<span class="special">;</span></code>
|
||||
</p></blockquote></div>
|
||||
<div class="blockquote"><blockquote class="blockquote"><p>
|
||||
<code class="computeroutput"><span class="keyword">inline</span> <span class="identifier">T</span>
|
||||
<span class="keyword">const</span><span class="special">&</span>
|
||||
<span class="identifier">get_optional_value_or</span> <span class="special">(</span>
|
||||
<span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span></code> <span class="emphasis"><em>(not a ref)</em></span><code class="computeroutput"><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">o</span><span class="special">,</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="keyword">default</span> <span class="special">)</span> <span class="special">;</span></code>
|
||||
</p></blockquote></div>
|
||||
<div class="blockquote"><blockquote class="blockquote"><p>
|
||||
<code class="computeroutput"><span class="keyword">inline</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">get_optional_value_or</span>
|
||||
<span class="special">(</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span></code>
|
||||
<span class="emphasis"><em>(not a ref)</em></span><code class="computeroutput"><span class="special">>&</span>
|
||||
<span class="identifier">o</span><span class="special">,</span> <span class="identifier">T</span><span class="special">&</span> <span class="keyword">default</span> <span class="special">)</span> <span class="special">;</span></code>
|
||||
</p></blockquote></div>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Returns:</strong></span> A reference to the contained
|
||||
value, if any, or <code class="computeroutput"><span class="keyword">default</span></code>.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Throws:</strong></span> Nothing.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Example:</strong></span>
|
||||
<pre class="programlisting"><span class="identifier">T</span> <span class="identifier">v</span><span class="special">,</span> <span class="identifier">z</span> <span class="special">;</span>
|
||||
<span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="identifier">def</span><span class="special">;</span>
|
||||
<span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">y</span> <span class="special">=</span> <span class="identifier">def</span><span class="special">.</span><span class="identifier">get_value_or</span><span class="special">(</span><span class="identifier">z</span><span class="special">);</span>
|
||||
<span class="identifier">assert</span> <span class="special">(</span> <span class="identifier">y</span> <span class="special">==</span> <span class="identifier">z</span> <span class="special">)</span> <span class="special">;</span>
|
||||
|
||||
<span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="identifier">opt</span> <span class="special">(</span> <span class="identifier">v</span> <span class="special">);</span>
|
||||
<span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">u</span> <span class="special">=</span> <span class="identifier">get_optional_value_or</span><span class="special">(</span><span class="identifier">opt</span><span class="special">,</span><span class="identifier">z</span><span class="special">);</span>
|
||||
<span class="identifier">assert</span> <span class="special">(</span> <span class="identifier">u</span> <span class="special">==</span> <span class="identifier">v</span> <span class="special">)</span> <span class="special">;</span>
|
||||
<span class="identifier">assert</span> <span class="special">(</span> <span class="identifier">u</span> <span class="special">!=</span> <span class="identifier">z</span> <span class="special">)</span> <span class="special">;</span>
|
||||
</pre>
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
<span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span>
|
||||
</p>
|
||||
<div class="blockquote"><blockquote class="blockquote"><p>
|
||||
<code class="computeroutput"><span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">&>::</span><span class="keyword">operator</span><span class="special">*()</span> <span class="keyword">const</span> <span class="special">;</span></code>
|
||||
</p></blockquote></div>
|
||||
<div class="blockquote"><blockquote class="blockquote"><p>
|
||||
<code class="computeroutput"><span class="identifier">T</span> <span class="special">&</span>
|
||||
<span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">&>::</span><span class="keyword">operator</span><span class="special">*();</span></code>
|
||||
</p></blockquote></div>
|
||||
<div class="blockquote"><blockquote class="blockquote"><p>
|
||||
<code class="computeroutput"><span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">&>::</span><span class="identifier">get</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span></code>
|
||||
</p></blockquote></div>
|
||||
@ -1290,6 +1252,84 @@
|
||||
<span class="bold"><strong>Notes:</strong></span> The requirement is asserted via
|
||||
<code class="computeroutput"><span class="identifier">BOOST_ASSERT</span><span class="special">()</span></code>.
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
<span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span>
|
||||
</p>
|
||||
<a name="reference_optional_operator_asterisk"></a><div class="blockquote"><blockquote class="blockquote"><p>
|
||||
<code class="computeroutput"><span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span></code>
|
||||
<span class="emphasis"><em>(not a ref)</em></span><code class="computeroutput"><span class="special">>::</span><span class="keyword">operator</span><span class="special">*()</span> <span class="keyword">const</span><span class="special">&</span> <span class="special">;</span></code>
|
||||
</p></blockquote></div>
|
||||
<div class="blockquote"><blockquote class="blockquote"><p>
|
||||
<code class="computeroutput"><span class="identifier">T</span><span class="special">&</span>
|
||||
<span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span></code> <span class="emphasis"><em>(not a ref)</em></span><code class="computeroutput"><span class="special">>::</span><span class="keyword">operator</span><span class="special">*()</span> <span class="special">&;</span></code>
|
||||
</p></blockquote></div>
|
||||
<div class="blockquote"><blockquote class="blockquote"><p>
|
||||
<code class="computeroutput"><span class="identifier">T</span><span class="special">&&</span>
|
||||
<span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span></code> <span class="emphasis"><em>(not a ref)</em></span><code class="computeroutput"><span class="special">>::</span><span class="keyword">operator</span><span class="special">*()</span> <span class="special">&&;</span></code>
|
||||
</p></blockquote></div>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Requires:</strong></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is initialized
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Returns:</strong></span> A reference to the contained
|
||||
value
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Throws:</strong></span> Nothing.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Notes:</strong></span> The requirement is asserted via
|
||||
<code class="computeroutput"><span class="identifier">BOOST_ASSERT</span><span class="special">()</span></code>.
|
||||
On compilers that do not support ref-qualifiers on member functions these
|
||||
three overloads are replaced with the classical two: a <code class="computeroutput"><span class="keyword">const</span></code>
|
||||
and non-<code class="computeroutput"><span class="keyword">const</span></code> member functions.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Example:</strong></span>
|
||||
<pre class="programlisting"><span class="identifier">T</span> <span class="identifier">v</span> <span class="special">;</span>
|
||||
<span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="identifier">opt</span> <span class="special">(</span> <span class="identifier">v</span> <span class="special">);</span>
|
||||
<span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">u</span> <span class="special">=</span> <span class="special">*</span><span class="identifier">opt</span><span class="special">;</span>
|
||||
<span class="identifier">assert</span> <span class="special">(</span> <span class="identifier">u</span> <span class="special">==</span> <span class="identifier">v</span> <span class="special">)</span> <span class="special">;</span>
|
||||
<span class="identifier">T</span> <span class="identifier">w</span> <span class="special">;</span>
|
||||
<span class="special">*</span><span class="identifier">opt</span> <span class="special">=</span> <span class="identifier">w</span> <span class="special">;</span>
|
||||
<span class="identifier">assert</span> <span class="special">(</span> <span class="special">*</span><span class="identifier">opt</span> <span class="special">==</span> <span class="identifier">w</span> <span class="special">)</span> <span class="special">;</span>
|
||||
</pre>
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
<span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span>
|
||||
</p>
|
||||
<div class="blockquote"><blockquote class="blockquote"><p>
|
||||
<code class="computeroutput"><span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">&>::</span><span class="keyword">operator</span><span class="special">*()</span> <span class="keyword">const</span><span class="special">&</span> <span class="special">;</span></code>
|
||||
</p></blockquote></div>
|
||||
<div class="blockquote"><blockquote class="blockquote"><p>
|
||||
<code class="computeroutput"><span class="identifier">T</span> <span class="special">&</span>
|
||||
<span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">&>::</span><span class="keyword">operator</span><span class="special">*()</span> <span class="special">&</span> <span class="special">;</span></code>
|
||||
</p></blockquote></div>
|
||||
<div class="blockquote"><blockquote class="blockquote"><p>
|
||||
<code class="computeroutput"><span class="identifier">T</span> <span class="special">&</span>
|
||||
<span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">&>::</span><span class="keyword">operator</span><span class="special">*()</span> <span class="special">&&</span> <span class="special">;</span></code>
|
||||
</p></blockquote></div>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Requires: </strong></span> <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code> is initialized
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Returns:</strong></span> <span class="underline">The</span>
|
||||
reference contained.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Throws:</strong></span> Nothing.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Notes:</strong></span> The requirement is asserted via
|
||||
<code class="computeroutput"><span class="identifier">BOOST_ASSERT</span><span class="special">()</span></code>.
|
||||
On compilers that do not support ref-qualifiers on member functions these
|
||||
three overloads are replaced with the classical two: a <code class="computeroutput"><span class="keyword">const</span></code>
|
||||
and non-<code class="computeroutput"><span class="keyword">const</span></code> member functions.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Example:</strong></span>
|
||||
<pre class="programlisting"><span class="identifier">T</span> <span class="identifier">v</span> <span class="special">;</span>
|
||||
@ -1302,6 +1342,137 @@
|
||||
</pre>
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
<span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span>
|
||||
</p>
|
||||
<a name="reference_optional_value"></a><div class="blockquote"><blockquote class="blockquote"><p>
|
||||
<code class="computeroutput"><span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">value</span><span class="special">()</span> <span class="keyword">const</span><span class="special">&</span> <span class="special">;</span></code>
|
||||
</p></blockquote></div>
|
||||
<div class="blockquote"><blockquote class="blockquote"><p>
|
||||
<code class="computeroutput"><span class="identifier">T</span><span class="special">&</span>
|
||||
<span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">value</span><span class="special">()</span> <span class="special">&</span> <span class="special">;</span></code>
|
||||
</p></blockquote></div>
|
||||
<div class="blockquote"><blockquote class="blockquote"><p>
|
||||
<code class="computeroutput"><span class="identifier">T</span><span class="special">&&</span>
|
||||
<span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">value</span><span class="special">()</span> <span class="special">&&</span> <span class="special">;</span></code>
|
||||
</p></blockquote></div>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Returns:</strong></span> A reference to the contained
|
||||
value, if <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
|
||||
is initialized.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Throws:</strong></span> An instance of <code class="computeroutput"><span class="identifier">bad_optional_access</span></code>,
|
||||
if <code class="computeroutput"><span class="special">*</span><span class="keyword">this</span></code>
|
||||
is not initialized.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Notes:</strong></span> On compilers that do not support
|
||||
ref-qualifiers on member functions these three overloads are replaced with
|
||||
the classical two: a <code class="computeroutput"><span class="keyword">const</span></code>
|
||||
and non-<code class="computeroutput"><span class="keyword">const</span></code> member functions.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Example:</strong></span>
|
||||
<pre class="programlisting"><span class="identifier">T</span> <span class="identifier">v</span> <span class="special">;</span>
|
||||
<span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="identifier">o0</span><span class="special">,</span> <span class="identifier">o1</span> <span class="special">(</span> <span class="identifier">v</span> <span class="special">);</span>
|
||||
<span class="identifier">assert</span> <span class="special">(</span> <span class="identifier">o1</span><span class="special">.</span><span class="identifier">value</span><span class="special">()</span> <span class="special">==</span> <span class="identifier">v</span> <span class="special">);</span>
|
||||
|
||||
<span class="keyword">try</span> <span class="special">{</span>
|
||||
<span class="identifier">o0</span><span class="special">.</span><span class="identifier">value</span><span class="special">();</span> <span class="comment">// throws</span>
|
||||
<span class="identifier">assert</span> <span class="special">(</span> <span class="keyword">false</span> <span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
<span class="keyword">catch</span><span class="special">(</span><span class="identifier">bad_optional_access</span><span class="special">&)</span> <span class="special">{</span>
|
||||
<span class="identifier">assert</span> <span class="special">(</span> <span class="keyword">true</span> <span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span>
|
||||
</li>
|
||||
</ul></div>
|
||||
<a name="reference_optional_value_or"></a><div class="blockquote"><blockquote class="blockquote"><p>
|
||||
<code class="computeroutput"><span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">></span> <span class="identifier">T</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">value_or</span><span class="special">(</span><span class="identifier">U</span> <span class="special">&&</span>
|
||||
<span class="identifier">v</span><span class="special">)</span> <span class="keyword">const</span><span class="special">&</span> <span class="special">;</span></code>
|
||||
</p></blockquote></div>
|
||||
<div class="blockquote"><blockquote class="blockquote"><p>
|
||||
<code class="computeroutput"><span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">></span> <span class="identifier">T</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">value_or</span><span class="special">(</span><span class="identifier">U</span> <span class="special">&&</span>
|
||||
<span class="identifier">v</span><span class="special">)</span> <span class="special">&&</span> <span class="special">;</span></code>
|
||||
</p></blockquote></div>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Requires:</strong></span> <code class="computeroutput"><span class="identifier">T</span></code>
|
||||
is CopyConstructible.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Returns:</strong></span> First overload: <code class="computeroutput"><span class="keyword">bool</span><span class="special">(*</span><span class="keyword">this</span><span class="special">)</span> <span class="special">?</span> <span class="special">**</span><span class="keyword">this</span> <span class="special">:</span> <span class="keyword">static_cast</span><span class="special"><</span><span class="identifier">T</span><span class="special">>(</span><span class="identifier">forward</span><span class="special"><</span><span class="identifier">U</span><span class="special">>(</span><span class="identifier">v</span><span class="special">))</span></code>.
|
||||
second overload: <code class="computeroutput"><span class="keyword">bool</span><span class="special">(*</span><span class="keyword">this</span><span class="special">)</span> <span class="special">?</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">move</span><span class="special">(**</span><span class="keyword">this</span><span class="special">)</span> <span class="special">:</span>
|
||||
<span class="keyword">static_cast</span><span class="special"><</span><span class="identifier">T</span><span class="special">>(</span><span class="identifier">forward</span><span class="special"><</span><span class="identifier">U</span><span class="special">>(</span><span class="identifier">v</span><span class="special">))</span></code>.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Throws:</strong></span> Any exception thrown by the selected
|
||||
constructor of <code class="computeroutput"><span class="identifier">T</span></code>.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Notes:</strong></span> On compilers that do not support
|
||||
ref-qualifiers on member functions these three overloads are replaced with
|
||||
the classical two: a <code class="computeroutput"><span class="keyword">const</span></code>
|
||||
and non-<code class="computeroutput"><span class="keyword">const</span></code> member functions.
|
||||
On compilers without rvalue reference support the type of <code class="computeroutput"><span class="identifier">v</span></code> becomes <code class="computeroutput"><span class="identifier">U</span>
|
||||
<span class="keyword">const</span><span class="special">&</span></code>.
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
<span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span>
|
||||
</p>
|
||||
<a name="reference_optional_get_value_or_value"></a><div class="blockquote"><blockquote class="blockquote"><p>
|
||||
<code class="computeroutput"><span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span></code>
|
||||
<span class="emphasis"><em>(not a ref)</em></span><code class="computeroutput"><span class="special">>::</span><span class="identifier">get_value_or</span><span class="special">(</span>
|
||||
<span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="keyword">default</span><span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span></code>
|
||||
</p></blockquote></div>
|
||||
<div class="blockquote"><blockquote class="blockquote"><p>
|
||||
<code class="computeroutput"><span class="identifier">T</span><span class="special">&</span>
|
||||
<span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span></code> <span class="emphasis"><em>(not a ref)</em></span><code class="computeroutput"><span class="special">>::</span><span class="identifier">get_value_or</span><span class="special">(</span> <span class="identifier">T</span><span class="special">&</span>
|
||||
<span class="keyword">default</span> <span class="special">)</span>
|
||||
<span class="special">;</span></code>
|
||||
</p></blockquote></div>
|
||||
<div class="blockquote"><blockquote class="blockquote"><p>
|
||||
<code class="computeroutput"><span class="keyword">inline</span> <span class="identifier">T</span>
|
||||
<span class="keyword">const</span><span class="special">&</span>
|
||||
<span class="identifier">get_optional_value_or</span> <span class="special">(</span>
|
||||
<span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span></code> <span class="emphasis"><em>(not a ref)</em></span><code class="computeroutput"><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">o</span><span class="special">,</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="keyword">default</span> <span class="special">)</span> <span class="special">;</span></code>
|
||||
</p></blockquote></div>
|
||||
<div class="blockquote"><blockquote class="blockquote"><p>
|
||||
<code class="computeroutput"><span class="keyword">inline</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">get_optional_value_or</span>
|
||||
<span class="special">(</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span></code>
|
||||
<span class="emphasis"><em>(not a ref)</em></span><code class="computeroutput"><span class="special">>&</span>
|
||||
<span class="identifier">o</span><span class="special">,</span> <span class="identifier">T</span><span class="special">&</span> <span class="keyword">default</span> <span class="special">)</span> <span class="special">;</span></code>
|
||||
</p></blockquote></div>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Deprecated:</strong></span> Use <code class="computeroutput"><span class="identifier">value_or</span><span class="special">()</span></code> instead.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Returns:</strong></span> A reference to the contained
|
||||
value, if any, or <code class="computeroutput"><span class="keyword">default</span></code>.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Throws:</strong></span> Nothing.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Example:</strong></span>
|
||||
<pre class="programlisting"><span class="identifier">T</span> <span class="identifier">v</span><span class="special">,</span> <span class="identifier">z</span> <span class="special">;</span>
|
||||
<span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="identifier">def</span><span class="special">;</span>
|
||||
<span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">y</span> <span class="special">=</span> <span class="identifier">def</span><span class="special">.</span><span class="identifier">get_value_or</span><span class="special">(</span><span class="identifier">z</span><span class="special">);</span>
|
||||
<span class="identifier">assert</span> <span class="special">(</span> <span class="identifier">y</span> <span class="special">==</span> <span class="identifier">z</span> <span class="special">)</span> <span class="special">;</span>
|
||||
|
||||
<span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="identifier">opt</span> <span class="special">(</span> <span class="identifier">v</span> <span class="special">);</span>
|
||||
<span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">u</span> <span class="special">=</span> <span class="identifier">get_optional_value_or</span><span class="special">(</span><span class="identifier">opt</span><span class="special">,</span><span class="identifier">z</span><span class="special">);</span>
|
||||
<span class="identifier">assert</span> <span class="special">(</span> <span class="identifier">u</span> <span class="special">==</span> <span class="identifier">v</span> <span class="special">)</span> <span class="special">;</span>
|
||||
<span class="identifier">assert</span> <span class="special">(</span> <span class="identifier">u</span> <span class="special">!=</span> <span class="identifier">z</span> <span class="special">)</span> <span class="special">;</span>
|
||||
</pre>
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
<span class="inlinemediaobject"><img src="../images/space.png" alt="space"></span>
|
||||
</p>
|
||||
@ -1798,7 +1969,7 @@
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="synopsis.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="examples.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
<a accesskey="p" href="synopsis.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="dependencies_and_portability.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -6,7 +6,7 @@
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||
<link rel="home" href="../index.html" title="Chapter 1. Boost.Optional">
|
||||
<link rel="up" href="../index.html" title="Chapter 1. Boost.Optional">
|
||||
<link rel="prev" href="motivation.html" title="Motivation">
|
||||
<link rel="prev" href="tutorial.html" title="Tutorial">
|
||||
<link rel="next" href="synopsis.html" title="Synopsis">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
@ -20,7 +20,7 @@
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="motivation.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="synopsis.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
<a accesskey="p" href="tutorial.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="synopsis.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
@ -39,12 +39,12 @@
|
||||
In C++, we can <span class="emphasis"><em>declare</em></span> an object (a variable) of type
|
||||
<code class="computeroutput"><span class="identifier">T</span></code>, and we can give this variable
|
||||
an <span class="emphasis"><em>initial value</em></span> (through an <span class="emphasis"><em>initializer</em></span>.
|
||||
(c.f. 8.5)). When a declaration includes a non-empty initializer (an initial
|
||||
(cf. 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
|
||||
<span class="bold"><strong>uninitialized</strong></span>. Its actual value exist but
|
||||
has an <span class="emphasis"><em>indeterminate initial value</em></span> (c.f. 8.5.9). <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code> intends
|
||||
has an <span class="emphasis"><em>indeterminate initial value</em></span> (cf. 8.5/11). <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code> 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
|
||||
@ -67,13 +67,12 @@
|
||||
special value: <code class="computeroutput"><span class="identifier">EOF</span></code>, <code class="computeroutput"><span class="identifier">npos</span></code>, -1, etc... This is equivalent to
|
||||
adding the special value to the set of possible values of a given type. This
|
||||
super set of <code class="computeroutput"><span class="identifier">T</span></code> plus some
|
||||
<span class="emphasis"><em>nil_t</em></span>—were <code class="computeroutput"><span class="identifier">nil_t</span></code>
|
||||
is some stateless POD-can be modeled in modern languages as a <span class="bold"><strong>discriminated
|
||||
union</strong></span> of T and nil_t. Discriminated unions are often called <span class="emphasis"><em>variants</em></span>.
|
||||
A variant has a <span class="emphasis"><em>current type</em></span>, which in our case is either
|
||||
<code class="computeroutput"><span class="identifier">T</span></code> or <code class="computeroutput"><span class="identifier">nil_t</span></code>.
|
||||
Using the <a href="../../../../variant/index.html" target="_top">Boost.Variant</a>
|
||||
library, this model can be implemented in terms of <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">variant</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span><span class="identifier">nil_t</span><span class="special">></span></code>.
|
||||
<span class="emphasis"><em>nil_t</em></span>—where <code class="computeroutput"><span class="identifier">nil_t</span></code>
|
||||
is some stateless POD—can be modeled in modern languages as a <span class="bold"><strong>discriminated union</strong></span> of T and nil_t. Discriminated
|
||||
unions are often called <span class="emphasis"><em>variants</em></span>. A variant has a <span class="emphasis"><em>current
|
||||
type</em></span>, which in our case is either <code class="computeroutput"><span class="identifier">T</span></code>
|
||||
or <code class="computeroutput"><span class="identifier">nil_t</span></code>. Using the <a href="../../../../variant/index.html" target="_top">Boost.Variant</a> library, this model
|
||||
can be implemented in terms of <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">variant</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span><span class="identifier">nil_t</span><span class="special">></span></code>.
|
||||
There is precedent for a discriminated union as a model for an optional value:
|
||||
the <a href="http://www.haskell.org/" target="_top">Haskell</a> <span class="bold"><strong>Maybe</strong></span>
|
||||
built-in type constructor. Thus, a discriminated union <code class="computeroutput"><span class="identifier">T</span><span class="special">+</span><span class="identifier">nil_t</span></code>
|
||||
@ -329,8 +328,8 @@
|
||||
Such a <span class="emphasis"><em>de facto</em></span> idiom for referring to optional objects
|
||||
can be formalized in the form of a concept: the <a href="../../../../utility/OptionalPointee.html" target="_top">OptionalPointee</a>
|
||||
concept. This concept captures the syntactic usage of operators <code class="computeroutput"><span class="special">*</span></code>, <code class="computeroutput"><span class="special">-></span></code>
|
||||
and conversion to <code class="computeroutput"><span class="keyword">bool</span></code> to convey
|
||||
the notion of optionality.
|
||||
and contextual conversion to <code class="computeroutput"><span class="keyword">bool</span></code>
|
||||
to convey the notion of optionality.
|
||||
</p>
|
||||
<p>
|
||||
However, pointers are good to <span class="underline">refer</span>
|
||||
@ -407,7 +406,7 @@
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="motivation.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="synopsis.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
<a accesskey="p" href="tutorial.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="synopsis.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
128
doc/html/boost_optional/discussion.html
Normal file
128
doc/html/boost_optional/discussion.html
Normal file
@ -0,0 +1,128 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Discussion</title>
|
||||
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||
<link rel="home" href="../index.html" title="Chapter 1. Boost.Optional">
|
||||
<link rel="up" href="../index.html" title="Chapter 1. Boost.Optional">
|
||||
<link rel="prev" href="quick_start.html" title="Quick Start">
|
||||
<link rel="next" href="development.html" title="Development">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="quick_start.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="development.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="boost_optional.discussion"></a><a class="link" href="discussion.html" title="Discussion">Discussion</a>
|
||||
</h2></div></div></div>
|
||||
<p>
|
||||
Consider these functions which should return a value but which might not have
|
||||
a value to return:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
(A) <code class="computeroutput"><span class="keyword">double</span> <span class="identifier">sqrt</span><span class="special">(</span><span class="keyword">double</span> <span class="identifier">n</span> <span class="special">);</span></code>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
(B) <code class="computeroutput"><span class="keyword">char</span> <span class="identifier">get_async_input</span><span class="special">();</span></code>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
(C) <code class="computeroutput"><span class="identifier">point</span> <span class="identifier">polygon</span><span class="special">::</span><span class="identifier">get_any_point_effectively_inside</span><span class="special">();</span></code>
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
There are different approaches to the issue of not having a value to return.
|
||||
</p>
|
||||
<p>
|
||||
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 assert 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.
|
||||
</p>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
<p>
|
||||
A similar situation occurs with function (C): it is conceptually an error to
|
||||
ask a <span class="emphasis"><em>null-area</em></span> 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.
|
||||
</p>
|
||||
<p>
|
||||
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 <code class="computeroutput"><span class="identifier">EOF</span></code>, <code class="computeroutput"><span class="identifier">string</span><span class="special">::</span><span class="identifier">npos</span></code>, points
|
||||
at infinity, etc...
|
||||
</p>
|
||||
<p>
|
||||
When those values exist, i.e. the return type can hold all meaningful values
|
||||
<span class="emphasis"><em>plus</em></span> the <span class="emphasis"><em>signal</em></span> 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 <code class="computeroutput"><span class="keyword">int</span></code> in place
|
||||
of <code class="computeroutput"><span class="keyword">char</span></code>; or a compound type, such
|
||||
as <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="identifier">point</span><span class="special">,</span><span class="keyword">bool</span><span class="special">></span></code>.
|
||||
</p>
|
||||
<p>
|
||||
Returning a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span><span class="keyword">bool</span><span class="special">></span></code>, 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:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="keyword">char</span><span class="special">,</span><span class="keyword">bool</span><span class="special">></span> <span class="identifier">get_async_input</span><span class="special">();</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="identifier">point</span><span class="special">,</span><span class="keyword">bool</span><span class="special">></span> <span class="identifier">polygon</span><span class="special">::</span><span class="identifier">get_any_point_effectively_inside</span><span class="special">();</span>
|
||||
</pre>
|
||||
<p>
|
||||
These functions use a consistent interface for dealing with possibly nonexistent
|
||||
results:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="identifier">point</span><span class="special">,</span><span class="keyword">bool</span><span class="special">></span> <span class="identifier">p</span> <span class="special">=</span> <span class="identifier">poly</span><span class="special">.</span><span class="identifier">get_any_point_effectively_inside</span><span class="special">();</span>
|
||||
<span class="keyword">if</span> <span class="special">(</span> <span class="identifier">p</span><span class="special">.</span><span class="identifier">second</span> <span class="special">)</span>
|
||||
<span class="identifier">flood_fill</span><span class="special">(</span><span class="identifier">p</span><span class="special">.</span><span class="identifier">first</span><span class="special">);</span>
|
||||
</pre>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
<p>
|
||||
Clearly, we need a better idiom.
|
||||
</p>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014 Andrzej Krzemieński<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
</div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="quick_start.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="development.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -95,8 +95,8 @@
|
||||
</p>
|
||||
<p>
|
||||
Unless <code class="computeroutput"><span class="identifier">T</span></code>'s constructor or assignment
|
||||
throws, <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code> does
|
||||
not throw anything else on its own. A throw during assignment never changes
|
||||
throws, assignments to <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>
|
||||
do not throw anything else on its own. A throw during assignment never changes
|
||||
the initialization state of any optional object involved:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="identifier">opt1</span><span class="special">(</span><span class="identifier">val1</span><span class="special">);</span>
|
||||
@ -118,6 +118,13 @@
|
||||
This also applies to move assignments/constructors. However, move operations
|
||||
are made no-throw more often.
|
||||
</p>
|
||||
<p>
|
||||
Operation <code class="computeroutput"><span class="identifier">emplace</span></code> provides
|
||||
basic exception safety guarantee. If it throws, the optional object becomes
|
||||
uninitialized regardless of its initial state, and its previous contained value
|
||||
(if any) is destroyed. It doesn't call any assignment or move/copy constructor
|
||||
on <code class="computeroutput"><span class="identifier">T</span></code>.
|
||||
</p>
|
||||
<h4>
|
||||
<a name="boost_optional.exception_safety_guarantees.h0"></a>
|
||||
<span class="phrase"><a name="boost_optional.exception_safety_guarantees.swap"></a></span><a class="link" href="exception_safety_guarantees.html#boost_optional.exception_safety_guarantees.swap">Swap</a>
|
||||
|
@ -6,7 +6,7 @@
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||
<link rel="home" href="../index.html" title="Chapter 1. Boost.Optional">
|
||||
<link rel="up" href="../index.html" title="Chapter 1. Boost.Optional">
|
||||
<link rel="prev" href="rebinding_semantics_for_assignment_of_optional_references.html" title="Rebinding semantics for assignment of optional references">
|
||||
<link rel="prev" href="detailed_semantics.html" title="Detailed Semantics">
|
||||
<link rel="next" href="a_note_about_optional_bool_.html" title="A note about optional<bool>">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
@ -20,7 +20,7 @@
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="rebinding_semantics_for_assignment_of_optional_references.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="a_note_about_optional_bool_.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
<a accesskey="p" href="detailed_semantics.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="a_note_about_optional_bool_.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
@ -190,7 +190,7 @@
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="rebinding_semantics_for_assignment_of_optional_references.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="a_note_about_optional_bool_.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
<a accesskey="p" href="detailed_semantics.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="a_note_about_optional_bool_.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -6,7 +6,7 @@
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||
<link rel="home" href="../index.html" title="Chapter 1. Boost.Optional">
|
||||
<link rel="up" href="../index.html" title="Chapter 1. Boost.Optional">
|
||||
<link rel="prev" href="examples.html" title="Examples">
|
||||
<link rel="prev" href="detailed_semantics.html" title="Detailed Semantics">
|
||||
<link rel="next" href="rebinding_semantics_for_assignment_of_optional_references.html" title="Rebinding semantics for assignment of optional references">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
@ -20,7 +20,7 @@
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="examples.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="rebinding_semantics_for_assignment_of_optional_references.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
<a accesskey="p" href="detailed_semantics.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="rebinding_semantics_for_assignment_of_optional_references.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
@ -77,7 +77,7 @@
|
||||
On compilers that do not conform to Standard C++ rules of reference binding,
|
||||
operations on optional references might give adverse results: rather than
|
||||
binding a reference to a designated object they may create an unexpected
|
||||
temporary and bind to it. For more details see <a class="link" href="dependencies_and_portability.html#boost_optional.dependencies_and_portability.optional_reference_binding" title="Optional Reference Binding">Dependencies
|
||||
temporary and bind to it. For more details see <a class="link" href="dependencies_and_portability/optional_reference_binding.html" title="Optional Reference Binding">Dependencies
|
||||
and Portability section</a>.
|
||||
</p></td></tr>
|
||||
</table></div>
|
||||
@ -108,7 +108,7 @@
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="examples.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="rebinding_semantics_for_assignment_of_optional_references.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
<a accesskey="p" href="detailed_semantics.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="rebinding_semantics_for_assignment_of_optional_references.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
152
doc/html/boost_optional/quick_start.html
Normal file
152
doc/html/boost_optional/quick_start.html
Normal file
@ -0,0 +1,152 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Quick Start</title>
|
||||
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||
<link rel="home" href="../index.html" title="Boost.Optional">
|
||||
<link rel="up" href="../index.html" title="Boost.Optional">
|
||||
<link rel="prev" href="../index.html" title="Boost.Optional">
|
||||
<link rel="next" href="quick_start/optional_automatic_variables.html" title="Optional automatic variables">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="../index.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="quick_start/optional_automatic_variables.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="boost_optional.quick_start"></a><a class="link" href="quick_start.html" title="Quick Start">Quick Start</a>
|
||||
</h2></div></div></div>
|
||||
<div class="toc"><dl class="toc">
|
||||
<dt><span class="section"><a href="quick_start.html#boost_optional.quick_start.optional_return_values">Optional
|
||||
return values</a></span></dt>
|
||||
<dt><span class="section"><a href="quick_start/optional_automatic_variables.html">Optional
|
||||
automatic variables</a></span></dt>
|
||||
<dt><span class="section"><a href="quick_start/optional_data_members.html">Optional
|
||||
data members</a></span></dt>
|
||||
<dt><span class="section"><a href="quick_start/bypassing_unnecessary_default_construction.html">Bypassing
|
||||
unnecessary default construction</a></span></dt>
|
||||
<dt><span class="section"><a href="quick_start/storage_in_containers.html">Storage
|
||||
in containers</a></span></dt>
|
||||
</dl></div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_optional.quick_start.optional_return_values"></a><a class="link" href="quick_start.html#boost_optional.quick_start.optional_return_values" title="Optional return values">Optional
|
||||
return values</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
Let's write and use a converter function that converts an a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
|
||||
to an <code class="computeroutput"><span class="keyword">int</span></code>. It is possible that
|
||||
for a given string (e.g. <code class="computeroutput"><span class="string">"cat"</span></code>)
|
||||
there exist no value of type <code class="computeroutput"><span class="keyword">int</span></code>
|
||||
capable of representing the conversion result. We do not consider such situation
|
||||
an error. We expect that the converter can be used only to check if the conversion
|
||||
is possible. A natural signature for this function can be:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">optional</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">optionl</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">convert</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&</span> <span class="identifier">text</span><span class="special">);</span>
|
||||
</pre>
|
||||
<p>
|
||||
All necessary functionality can be included with one header <code class="computeroutput"><span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">optional</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span></code>.
|
||||
The above function signature means that the function can either return a
|
||||
value of type <code class="computeroutput"><span class="keyword">int</span></code> or a flag
|
||||
indicating that no value of <code class="computeroutput"><span class="keyword">int</span></code>
|
||||
is available. This does not indicate an error. It is like one additional
|
||||
value of <code class="computeroutput"><span class="keyword">int</span></code>. This is how we
|
||||
can use our function:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&</span> <span class="identifier">text</span> <span class="special">=</span> <span class="comment">/*... */</span><span class="special">;</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">optionl</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">oi</span> <span class="special">=</span> <span class="identifier">convert</span><span class="special">(</span><span class="identifier">text</span><span class="special">);</span> <span class="comment">// move-construct</span>
|
||||
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">oi</span><span class="special">)</span> <span class="comment">// contextual conversion to bool</span>
|
||||
<span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="special">*</span><span class="identifier">oi</span><span class="special">;</span> <span class="comment">// operator*</span>
|
||||
</pre>
|
||||
<p>
|
||||
In order to test if <code class="computeroutput"><span class="identifier">optional</span></code>
|
||||
contains a value, we use the contextual conversion to type <code class="computeroutput"><span class="keyword">bool</span></code>. Because of this we can combine the initialization
|
||||
of the optional object and the test into one instruction:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">if</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">optionl</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">oi</span> <span class="special">=</span> <span class="identifier">convert</span><span class="special">(</span><span class="identifier">text</span><span class="special">))</span>
|
||||
<span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="special">*</span><span class="identifier">oi</span><span class="special">;</span>
|
||||
</pre>
|
||||
<p>
|
||||
We extract the contained value with <code class="computeroutput"><span class="keyword">operator</span><span class="special">*</span></code> (and with <code class="computeroutput"><span class="keyword">operator</span><span class="special">-></span></code> where it makes sense). An attempt to
|
||||
extract the contained value of an uninitialized optional object is an <span class="emphasis"><em>undefined
|
||||
behaviour</em></span> (UB). This implementation guards the call with <code class="computeroutput"><span class="identifier">BOOST_ASSERT</span></code>. Therefore you should be sure
|
||||
that the contained value is there before extracting. For instance, the following
|
||||
code is reasonably UB-safe:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="special">*</span><span class="identifier">convert</span><span class="special">(</span><span class="string">"100"</span><span class="special">);</span>
|
||||
</pre>
|
||||
<p>
|
||||
This is because we know that string value <code class="computeroutput"><span class="string">"100"</span></code>
|
||||
converts to a valid value of <code class="computeroutput"><span class="keyword">int</span></code>.
|
||||
If you do not like this potential UB, you can use an alternative way of extracting
|
||||
the contained value:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">try</span> <span class="special">{</span>
|
||||
<span class="keyword">int</span> <span class="identifier">j</span> <span class="special">=</span> <span class="identifier">convert</span><span class="special">(</span><span class="identifier">text</span><span class="special">).</span><span class="identifier">value</span><span class="special">();</span>
|
||||
<span class="special">}</span>
|
||||
<span class="keyword">catch</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">bad_optional_access</span><span class="special">&)</span> <span class="special">{</span>
|
||||
<span class="comment">// deal with it</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
This version throws an exception upon an attempt to access a non-existent
|
||||
contained value. If your way of dealing with the missing value is to use
|
||||
some default, like <code class="computeroutput"><span class="number">0</span></code>, there exists
|
||||
a yet another alternative:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">k</span> <span class="special">=</span> <span class="identifier">convert</span><span class="special">(</span><span class="identifier">text</span><span class="special">).</span><span class="identifier">value_or</span><span class="special">(</span><span class="number">0</span><span class="special">);</span>
|
||||
</pre>
|
||||
<p>
|
||||
This uses the <code class="computeroutput"><span class="identifier">atoi</span></code>-like approach
|
||||
to conversions: if <code class="computeroutput"><span class="identifier">text</span></code> does
|
||||
not represent an integral number just return <code class="computeroutput"><span class="number">0</span></code>.
|
||||
Now, let's consider how function <code class="computeroutput"><span class="identifier">convert</span></code>
|
||||
can be implemented.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">optionl</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">convert</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&</span> <span class="identifier">text</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">stringstream</span> <span class="identifier">s</span><span class="special">(</span><span class="identifier">text</span><span class="special">);</span>
|
||||
<span class="keyword">int</span> <span class="identifier">i</span><span class="special">;</span>
|
||||
<span class="keyword">if</span> <span class="special">((</span><span class="identifier">s</span> <span class="special">>></span> <span class="identifier">i</span><span class="special">)</span> <span class="special">&&</span> <span class="identifier">s</span><span class="special">.</span><span class="identifier">get</span><span class="special">()</span> <span class="special">==</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">char_traits</span><span class="special"><</span><span class="keyword">char</span><span class="special">>::</span><span class="identifier">eof</span><span class="special">())</span>
|
||||
<span class="keyword">return</span> <span class="identifier">i</span><span class="special">;</span>
|
||||
<span class="keyword">else</span>
|
||||
<span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">none</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
Observe the two return statements. <code class="computeroutput"><span class="keyword">return</span>
|
||||
<span class="identifier">i</span></code> uses the converting constructor
|
||||
that can create <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>
|
||||
from <code class="computeroutput"><span class="identifier">T</span></code>. Thus constructed
|
||||
optional object is initialized and its value is a copy of <code class="computeroutput"><span class="identifier">i</span></code>.
|
||||
The other return statement uses another converting constructor from a special
|
||||
tag <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">none</span></code>. It is used to indicate that we want
|
||||
to create an uninitialized optional object.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014 Andrzej Krzemieński<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
</div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="../index.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="quick_start/optional_automatic_variables.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,75 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Bypassing unnecessary default construction</title>
|
||||
<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||
<link rel="home" href="../../index.html" title="Boost.Optional">
|
||||
<link rel="up" href="../quick_start.html" title="Quick Start">
|
||||
<link rel="prev" href="optional_data_members.html" title="Optional data members">
|
||||
<link rel="next" href="storage_in_containers.html" title="Storage in containers">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="optional_data_members.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../quick_start.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="storage_in_containers.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_optional.quick_start.bypassing_unnecessary_default_construction"></a><a class="link" href="bypassing_unnecessary_default_construction.html" title="Bypassing unnecessary default construction">Bypassing
|
||||
unnecessary default construction</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
Suppose we have class <code class="computeroutput"><span class="identifier">Date</span></code>,
|
||||
which does not have a default constructor: there is no good candidate for
|
||||
a default date. We have a function that returns two dates in form of a <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">tuple</span></code>:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">tuple</span><span class="special"><</span><span class="identifier">Date</span><span class="special">,</span> <span class="identifier">Date</span><span class="special">></span> <span class="identifier">getPeriod</span><span class="special">();</span>
|
||||
</pre>
|
||||
<p>
|
||||
In other place we want to use the result of <code class="computeroutput"><span class="identifier">getPeriod</span></code>,
|
||||
but want the two dates to be named: <code class="computeroutput"><span class="identifier">begin</span></code>
|
||||
and <code class="computeroutput"><span class="identifier">end</span></code>. We want to implement
|
||||
something like 'multiple return values':
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">Date</span> <span class="identifier">begin</span><span class="special">,</span> <span class="identifier">end</span><span class="special">;</span> <span class="comment">// Error: no default ctor!</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">tie</span><span class="special">(</span><span class="identifier">begin</span><span class="special">,</span> <span class="identifier">end</span><span class="special">)</span> <span class="special">=</span> <span class="identifier">getPeriod</span><span class="special">();</span>
|
||||
</pre>
|
||||
<p>
|
||||
The second line works already, this is the capability of Boost.Tuple library,
|
||||
but the first line won't work. We could set some invented initial dates,
|
||||
but it is confusing and may be an unacceptable cost, given that these values
|
||||
will be overwritten in the next line anyway. This is where <code class="computeroutput"><span class="identifier">optional</span></code> can help:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span><span class="special"><</span><span class="identifier">Date</span><span class="special">></span> <span class="identifier">begin</span><span class="special">,</span> <span class="identifier">end</span><span class="special">;</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">tie</span><span class="special">(</span><span class="identifier">begin</span><span class="special">,</span> <span class="identifier">end</span><span class="special">)</span> <span class="special">=</span> <span class="identifier">getPeriod</span><span class="special">();</span>
|
||||
</pre>
|
||||
<p>
|
||||
It works because inside <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">tie</span></code> a
|
||||
move-assignment from <code class="computeroutput"><span class="identifier">T</span></code> is
|
||||
invoked on <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>,
|
||||
which internally calls a move-constructor of <code class="computeroutput"><span class="identifier">T</span></code>.
|
||||
</p>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014 Andrzej Krzemieński<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
</div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="optional_data_members.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../quick_start.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="storage_in_containers.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,75 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Optional automatic variables</title>
|
||||
<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||
<link rel="home" href="../../index.html" title="Boost.Optional">
|
||||
<link rel="up" href="../quick_start.html" title="Quick Start">
|
||||
<link rel="prev" href="../quick_start.html" title="Quick Start">
|
||||
<link rel="next" href="optional_data_members.html" title="Optional data members">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="../quick_start.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../quick_start.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="optional_data_members.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_optional.quick_start.optional_automatic_variables"></a><a class="link" href="optional_automatic_variables.html" title="Optional automatic variables">Optional
|
||||
automatic variables</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
We could write function <code class="computeroutput"><span class="identifier">convert</span></code>
|
||||
in a slightly different manner, so that it has a single <code class="computeroutput"><span class="keyword">return</span></code>-statement:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">optionl</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">convert</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&</span> <span class="identifier">text</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">optionl</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">ans</span><span class="special">;</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">stringstream</span> <span class="identifier">s</span><span class="special">(</span><span class="identifier">text</span><span class="special">);</span>
|
||||
<span class="keyword">int</span> <span class="identifier">i</span><span class="special">;</span>
|
||||
<span class="keyword">if</span> <span class="special">((</span><span class="identifier">s</span> <span class="special">>></span> <span class="identifier">i</span><span class="special">)</span> <span class="special">&&</span> <span class="identifier">s</span><span class="special">.</span><span class="identifier">get</span><span class="special">()</span> <span class="special">==</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">char_traits</span><span class="special"><</span><span class="keyword">char</span><span class="special">>::</span><span class="identifier">eof</span><span class="special">())</span>
|
||||
<span class="identifier">ans</span> <span class="special">=</span> <span class="identifier">i</span><span class="special">;</span>
|
||||
|
||||
<span class="keyword">return</span> <span class="identifier">ans</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
The default constructor of <code class="computeroutput"><span class="identifier">optional</span></code>
|
||||
creates an unitialized optional object. Unlike with <code class="computeroutput"><span class="keyword">int</span></code>s
|
||||
you cannot have an <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span></code>
|
||||
in an indeterminate state. Its state is always well defined. Instruction
|
||||
<code class="computeroutput"><span class="identifier">ans</span> <span class="special">=</span>
|
||||
<span class="identifier">i</span></code> initializes the optional object.
|
||||
It uses the assignment from <code class="computeroutput"><span class="keyword">int</span></code>.
|
||||
In general, for <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>,
|
||||
when an assignment from <code class="computeroutput"><span class="identifier">T</span></code>
|
||||
is invoked, it can do two things. If the optional object is not initialized
|
||||
our case here), it initializes it with <code class="computeroutput"><span class="identifier">T</span></code>'s
|
||||
copy constructor. If the optional object is already initialized, it assigns
|
||||
the new value to it using <code class="computeroutput"><span class="identifier">T</span></code>'s
|
||||
copy assignment.
|
||||
</p>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014 Andrzej Krzemieński<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
</div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="../quick_start.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../quick_start.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="optional_data_members.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,92 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Optional data members</title>
|
||||
<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||
<link rel="home" href="../../index.html" title="Boost.Optional">
|
||||
<link rel="up" href="../quick_start.html" title="Quick Start">
|
||||
<link rel="prev" href="optional_automatic_variables.html" title="Optional automatic variables">
|
||||
<link rel="next" href="bypassing_unnecessary_default_construction.html" title="Bypassing unnecessary default construction">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="optional_automatic_variables.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../quick_start.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="bypassing_unnecessary_default_construction.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_optional.quick_start.optional_data_members"></a><a class="link" href="optional_data_members.html" title="Optional data members">Optional
|
||||
data members</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
Suppose we want to implement a <span class="emphasis"><em>lazy load</em></span> optimization.
|
||||
This is because we do not want to perform an expensive initialization of
|
||||
our <code class="computeroutput"><span class="identifier">Resource</span></code> until (if at
|
||||
all) it is really used. We can do it this way:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">Widget</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span><span class="special"><</span><span class="identifier">Resource</span><span class="special">></span> <span class="identifier">resource_</span><span class="special">;</span>
|
||||
|
||||
<span class="keyword">public</span><span class="special">:</span>
|
||||
<span class="identifier">Widget</span><span class="special">()</span> <span class="special">{}</span>
|
||||
|
||||
<span class="identifier">Resource</span><span class="special">&</span> <span class="identifier">getResource</span><span class="special">()</span> <span class="comment">// not thread-safe</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">resource_</span> <span class="special">==</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">none</span><span class="special">)</span>
|
||||
<span class="identifier">resource_</span><span class="special">.</span><span class="identifier">emplace</span><span class="special">(</span><span class="string">"resource"</span><span class="special">,</span> <span class="string">"arguments"</span><span class="special">);</span>
|
||||
|
||||
<span class="keyword">return</span> <span class="special">*</span><span class="identifier">resource_</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
<span class="special">};</span>
|
||||
</pre>
|
||||
<p>
|
||||
<code class="computeroutput"><span class="identifier">optional</span></code>'s default constructor
|
||||
creates an uninitialized optional. No call to <code class="computeroutput"><span class="identifier">Resource</span></code>'s
|
||||
default constructor is attempted. <code class="computeroutput"><span class="identifier">Resource</span></code>
|
||||
doesn't have to be <a href="http://www.sgi.com/tech/stl/DefaultConstructible.html" target="_top">Default
|
||||
Constructible</a>. In function <code class="computeroutput"><span class="identifier">getResource</span></code>
|
||||
we first check if <code class="computeroutput"><span class="identifier">resource_</span></code>
|
||||
is initialized. This time we do not use the contextual conversion to <code class="computeroutput"><span class="keyword">bool</span></code>, but a comparison with <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">none</span></code>. These two ways are equivalent. Function
|
||||
<code class="computeroutput"><span class="identifier">emplace</span></code> initializes the optional
|
||||
in-place by perfect-forwarding the arguments to the constructor of <code class="computeroutput"><span class="identifier">Resource</span></code>. No copy- or move-construction
|
||||
is involved here. <code class="computeroutput"><span class="identifier">Resource</span></code>
|
||||
doesn't even have to be <code class="computeroutput"><span class="identifier">MoveConstructible</span></code>.
|
||||
</p>
|
||||
<div class="note"><table border="0" summary="Note">
|
||||
<tr>
|
||||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Note]" src="../../../../../../doc/src/images/note.png"></td>
|
||||
<th align="left">Note</th>
|
||||
</tr>
|
||||
<tr><td align="left" valign="top"><p>
|
||||
Function <code class="computeroutput"><span class="identifier">emplace</span></code> is only
|
||||
available on compilers that support rvalue references and variadic templates.
|
||||
If your compiler does not support these features and you still need to
|
||||
avoid any move-constructions, use <a class="link" href="../tutorial/in_place_factories.html" title="In-Place Factories">In-Place
|
||||
Factories</a>.
|
||||
</p></td></tr>
|
||||
</table></div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014 Andrzej Krzemieński<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
</div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="optional_automatic_variables.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../quick_start.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="bypassing_unnecessary_default_construction.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
135
doc/html/boost_optional/quick_start/optional_return_values.html
Normal file
135
doc/html/boost_optional/quick_start/optional_return_values.html
Normal file
@ -0,0 +1,135 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Optional return values</title>
|
||||
<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||
<link rel="home" href="../../index.html" title="Chapter 1. Boost.Optional">
|
||||
<link rel="up" href="../quick_start.html" title="Quick Start">
|
||||
<link rel="prev" href="../quick_start.html" title="Quick Start">
|
||||
<link rel="next" href="optional_automatic_variables.html" title="Optional automatic variables">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="../quick_start.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../quick_start.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="optional_automatic_variables.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_optional.quick_start.optional_return_values"></a><a class="link" href="optional_return_values.html" title="Optional return values">Optional
|
||||
return values</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
Let's write and use a converter function that converts an a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>
|
||||
to an <code class="computeroutput"><span class="keyword">int</span></code>. It is possible that
|
||||
for a given string (e.g. <code class="computeroutput"><span class="string">"cat"</span></code>)
|
||||
there exist no value of type <code class="computeroutput"><span class="keyword">int</span></code>
|
||||
capable of representing the conversion result. We do not consider such situation
|
||||
an error. We expect that the converter can be used only to check if the conversion
|
||||
is possible. A natural signature for this function can be:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">optional</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">optionl</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">convert</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&</span> <span class="identifier">text</span><span class="special">);</span>
|
||||
</pre>
|
||||
<p>
|
||||
All necessary functionality can be included with one header <code class="computeroutput"><span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">optional</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span></code>.
|
||||
The above function signature means that the function can either return a
|
||||
value of type <code class="computeroutput"><span class="keyword">int</span></code> or a flag
|
||||
indicating that no value of <code class="computeroutput"><span class="keyword">int</span></code>
|
||||
is available. This does not indicate an error. It is like one additional
|
||||
value of <code class="computeroutput"><span class="keyword">int</span></code>. This is how we
|
||||
can use our function:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&</span> <span class="identifier">text</span> <span class="special">=</span> <span class="comment">/*... */</span><span class="special">;</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">optionl</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">oi</span> <span class="special">=</span> <span class="identifier">convert</span><span class="special">(</span><span class="identifier">text</span><span class="special">);</span> <span class="comment">// move-construct</span>
|
||||
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">oi</span><span class="special">)</span> <span class="comment">// contextual conversion to bool</span>
|
||||
<span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="special">*</span><span class="identifier">oi</span><span class="special">;</span> <span class="comment">// operator*</span>
|
||||
</pre>
|
||||
<p>
|
||||
In order to test if <code class="computeroutput"><span class="identifier">optional</span></code>
|
||||
contains a value, we use the contextual conversion to type <code class="computeroutput"><span class="keyword">bool</span></code>. Because of this we can combine the initialization
|
||||
of the optional object and the test into one instruction:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">if</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">optionl</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">oi</span> <span class="special">=</span> <span class="identifier">convert</span><span class="special">(</span><span class="identifier">text</span><span class="special">))</span>
|
||||
<span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="special">*</span><span class="identifier">oi</span><span class="special">;</span>
|
||||
</pre>
|
||||
<p>
|
||||
We extract the contained value with <code class="computeroutput"><span class="keyword">operator</span><span class="special">*</span></code> (and with <code class="computeroutput"><span class="keyword">operator</span><span class="special">-></span></code> where it makes sense). An attempt to
|
||||
extract the contained value of an uninitialized optional object is an <span class="emphasis"><em>undefined
|
||||
behaviour</em></span> (UB). This implementation guards the call with <code class="computeroutput"><span class="identifier">BOOST_ASSERT</span></code>. Therefore you should be sure
|
||||
that the contained value is there before extracting. For instance, the following
|
||||
code is reasonably UB-safe:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="special">*</span><span class="identifier">convert</span><span class="special">(</span><span class="string">"100"</span><span class="special">);</span>
|
||||
</pre>
|
||||
<p>
|
||||
This is because we know that string value <code class="computeroutput"><span class="string">"100"</span></code>
|
||||
converts to a valid value of <code class="computeroutput"><span class="keyword">int</span></code>.
|
||||
If you do not like this potential UB, you can use an alternative way of extracting
|
||||
the contained value:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">try</span> <span class="special">{</span>
|
||||
<span class="keyword">int</span> <span class="identifier">j</span> <span class="special">=</span> <span class="identifier">convert</span><span class="special">(</span><span class="identifier">text</span><span class="special">).</span><span class="identifier">value</span><span class="special">();</span>
|
||||
<span class="special">}</span>
|
||||
<span class="keyword">catch</span> <span class="special">(</span><span class="keyword">const</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">bad_optional_access</span><span class="special">&)</span> <span class="special">{</span>
|
||||
<span class="comment">// deal with it</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
This version throws an exception upon an attempt to access a non-existent
|
||||
contained value. If your way of dealing with the missing value is to use
|
||||
some default, like <code class="computeroutput"><span class="number">0</span></code>, there exists
|
||||
a yet another alternative:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">k</span> <span class="special">=</span> <span class="identifier">convert</span><span class="special">(</span><span class="identifier">text</span><span class="special">).</span><span class="identifier">value_or</span><span class="special">(</span><span class="number">0</span><span class="special">);</span>
|
||||
</pre>
|
||||
<p>
|
||||
This uses the <code class="computeroutput"><span class="identifier">atoi</span></code>-like approach
|
||||
to conversions: if <code class="computeroutput"><span class="identifier">text</span></code> does
|
||||
not represent an integral number just return <code class="computeroutput"><span class="number">0</span></code>.
|
||||
Now, let's consider how function <code class="computeroutput"><span class="identifier">convert</span></code>
|
||||
can be implemented.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">optionl</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">convert</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&</span> <span class="identifier">text</span><span class="special">)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">stringstream</span> <span class="identifier">s</span><span class="special">(</span><span class="identifier">text</span><span class="special">);</span>
|
||||
<span class="keyword">int</span> <span class="identifier">i</span><span class="special">;</span>
|
||||
<span class="keyword">if</span> <span class="special">((</span><span class="identifier">s</span> <span class="special">>></span> <span class="identifier">i</span><span class="special">)</span> <span class="special">&&</span> <span class="identifier">s</span><span class="special">.</span><span class="identifier">get</span><span class="special">()</span> <span class="special">==</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">char_traits</span><span class="special"><</span><span class="keyword">char</span><span class="special">>::</span><span class="identifier">eof</span><span class="special">())</span>
|
||||
<span class="keyword">return</span> <span class="identifier">i</span><span class="special">;</span>
|
||||
<span class="keyword">else</span>
|
||||
<span class="keyword">return</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">none</span><span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
Observe the two return statements. <code class="computeroutput"><span class="keyword">return</span>
|
||||
<span class="identifier">i</span></code> uses the converting constructor
|
||||
that can create <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>
|
||||
from <code class="computeroutput"><span class="identifier">T</span></code>. Thus constructed
|
||||
optional object is initialized and its value is a copy of <code class="computeroutput"><span class="identifier">i</span></code>.
|
||||
The other return statement uses another converting constructor from a special
|
||||
tag <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">none</span></code>. It is used to indicate that we want
|
||||
to create an uninitialized optional object.
|
||||
</p>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014 Andrzej Krzemieński<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
</div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="../quick_start.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../quick_start.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="optional_automatic_variables.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,69 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Storage in containers</title>
|
||||
<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||
<link rel="home" href="../../index.html" title="Boost.Optional">
|
||||
<link rel="up" href="../quick_start.html" title="Quick Start">
|
||||
<link rel="prev" href="bypassing_unnecessary_default_construction.html" title="Bypassing unnecessary default construction">
|
||||
<link rel="next" href="../../optional/tutorial.html" title="Tutorial">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="bypassing_unnecessary_default_construction.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../quick_start.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../../optional/tutorial.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_optional.quick_start.storage_in_containers"></a><a class="link" href="storage_in_containers.html" title="Storage in containers">Storage
|
||||
in containers</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
Suppose you want to ask users to choose some number (an <code class="computeroutput"><span class="keyword">int</span></code>).
|
||||
One of the valid responses is to choose nothing, which is represented by
|
||||
an uninitialized <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span></code>.
|
||||
You want to make a histogram showing how many times each choice was made.
|
||||
You can use an <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span></code>:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span><span class="special"><</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span><span class="special"><</span><span class="keyword">int</span><span class="special">>,</span> <span class="keyword">int</span><span class="special">></span> <span class="identifier">choices</span><span class="special">;</span>
|
||||
|
||||
<span class="keyword">for</span> <span class="special">(</span><span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> <span class="identifier">i</span> <span class="special"><</span> <span class="identifier">LIMIT</span><span class="special">;</span> <span class="special">++</span><span class="identifier">i</span><span class="special">)</span> <span class="special">{</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">choice</span> <span class="special">=</span> <span class="identifier">readChoice</span><span class="special">();</span>
|
||||
<span class="special">++</span><span class="identifier">choices</span><span class="special">[</span><span class="identifier">choice</span><span class="special">];</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
This works because <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>
|
||||
is <code class="computeroutput"><span class="identifier">LessThanComparable</span></code> whenever
|
||||
<code class="computeroutput"><span class="identifier">T</span></code> is <code class="computeroutput"><span class="identifier">LessThanComparable</span></code>.
|
||||
In this case the state of being uninitialized is treated as a yet another
|
||||
value of <code class="computeroutput"><span class="identifier">T</span></code>, which is compared
|
||||
less than any value of <code class="computeroutput"><span class="identifier">T</span></code>.
|
||||
So the set of values that type <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>
|
||||
can assume is {<code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">none</span></code>, -2147483648, -2147483647, ..., -1,
|
||||
0, 1, ..., 2147483647} (assuming a 32-bit <code class="computeroutput"><span class="keyword">int</span></code>).
|
||||
</p>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014 Andrzej Krzemieński<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
</div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="bypassing_unnecessary_default_construction.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../quick_start.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../../optional/tutorial.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
1963
doc/html/boost_optional/reference/detailed_semantics.html
Normal file
1963
doc/html/boost_optional/reference/detailed_semantics.html
Normal file
File diff suppressed because it is too large
Load Diff
174
doc/html/boost_optional/reference/synopsis.html
Normal file
174
doc/html/boost_optional/reference/synopsis.html
Normal file
@ -0,0 +1,174 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Synopsis</title>
|
||||
<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||
<link rel="home" href="../../index.html" title="Chapter 1. Boost.Optional">
|
||||
<link rel="up" href="../../optional/reference.html" title="Reference">
|
||||
<link rel="prev" href="../../optional/reference.html" title="Reference">
|
||||
<link rel="next" href="detailed_semantics.html" title="Detailed Semantics">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="../../optional/reference.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../../optional/reference.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="detailed_semantics.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_optional.reference.synopsis"></a><a class="link" href="synopsis.html" title="Synopsis">Synopsis</a>
|
||||
</h3></div></div></div>
|
||||
<pre class="programlisting"><code class="computeroutput"><span class="comment">// In Header: <</span></code><a href="../../../../../../boost/optional/optional.hpp" target="_top">boost/optional/optional.hpp</a><span class="comment">></span>
|
||||
|
||||
<span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span>
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span>
|
||||
<span class="keyword">class</span> <span class="identifier">optional</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">public</span> <span class="special">:</span>
|
||||
|
||||
<span class="comment">// (If T is of reference type, the parameters and results by reference are by value)</span>
|
||||
|
||||
<span class="identifier">optional</span> <span class="special">()</span> <span class="keyword">noexcept</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_constructor"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="identifier">optional</span> <span class="special">(</span> <span class="identifier">none_t</span> <span class="special">)</span> <span class="keyword">noexcept</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_constructor_none_t"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="identifier">optional</span> <span class="special">(</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">v</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_constructor_value"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="identifier">optional</span> <span class="special">(</span> <span class="identifier">T</span><span class="special">&&</span> <span class="identifier">v</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_constructor_move_value"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="comment">// [new in 1.34]</span>
|
||||
<span class="identifier">optional</span> <span class="special">(</span> <span class="keyword">bool</span> <span class="identifier">condition</span><span class="special">,</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">v</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_constructor_bool_value"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="identifier">optional</span> <span class="special">(</span> <span class="identifier">optional</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">rhs</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_constructor_optional"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="identifier">optional</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&&</span> <span class="identifier">rhs</span> <span class="special">)</span> <span class="keyword">noexcept</span><span class="special">(</span><span class="emphasis"><em>see below</em></span><span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_move_constructor_optional"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">></span> <span class="keyword">explicit</span> <span class="identifier">optional</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">U</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">rhs</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_constructor_other_optional"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">></span> <span class="keyword">explicit</span> <span class="identifier">optional</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">U</span><span class="special">>&&</span> <span class="identifier">rhs</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_move_constructor_other_optional"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">InPlaceFactory</span><span class="special">></span> <span class="keyword">explicit</span> <span class="identifier">optional</span> <span class="special">(</span> <span class="identifier">InPlaceFactory</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">f</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_constructor_factory"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">TypedInPlaceFactory</span><span class="special">></span> <span class="keyword">explicit</span> <span class="identifier">optional</span> <span class="special">(</span> <span class="identifier">TypedInPlaceFactory</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">f</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_constructor_factory"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="identifier">optional</span><span class="special">&</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span> <span class="identifier">none_t</span> <span class="special">)</span> <span class="keyword">noexcept</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_operator_equal_none_t"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="identifier">optional</span><span class="special">&</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">v</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_operator_equal_value"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="identifier">optional</span><span class="special">&</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span> <span class="identifier">T</span><span class="special">&&</span> <span class="identifier">v</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_operator_move_equal_value"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="identifier">optional</span><span class="special">&</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span> <span class="identifier">optional</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">rhs</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_operator_equal_optional"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="identifier">optional</span><span class="special">&</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&&</span> <span class="identifier">rhs</span> <span class="special">)</span> <span class="keyword">noexcept</span><span class="special">(</span><span class="emphasis"><em>see below</em></span><span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_operator_move_equal_optional"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">></span> <span class="identifier">optional</span><span class="special">&</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">U</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">rhs</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_operator_equal_other_optional"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">></span> <span class="identifier">optional</span><span class="special">&</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">U</span><span class="special">>&&</span> <span class="identifier">rhs</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_operator_move_equal_other_optional"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span><span class="special">...</span> <span class="identifier">Args</span><span class="special">></span> <span class="keyword">void</span> <span class="identifier">emplace</span> <span class="special">(</span> <span class="identifier">Args</span><span class="special">...&&</span> <span class="identifier">args</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_emplace"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">InPlaceFactory</span><span class="special">></span> <span class="identifier">optional</span><span class="special">&</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span> <span class="identifier">InPlaceFactory</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">f</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_operator_equal_factory"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">TypedInPlaceFactory</span><span class="special">></span> <span class="identifier">optional</span><span class="special">&</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span> <span class="identifier">TypedInPlaceFactory</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">f</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_operator_equal_factory"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">get</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_get"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
<span class="identifier">T</span><span class="special">&</span> <span class="identifier">get</span><span class="special">()</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_get"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="identifier">T</span> <span class="keyword">const</span><span class="special">*</span> <span class="keyword">operator</span> <span class="special">->()</span> <span class="keyword">const</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_operator_arrow"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
<span class="identifier">T</span><span class="special">*</span> <span class="keyword">operator</span> <span class="special">->()</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_operator_arrow"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="keyword">operator</span> <span class="special">*()</span> <span class="keyword">const</span><span class="special">&</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_operator_asterisk"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
<span class="identifier">T</span><span class="special">&</span> <span class="keyword">operator</span> <span class="special">*()</span> <span class="special">&;</span> <a class="link" href="detailed_semantics.html#reference_optional_operator_asterisk"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
<span class="identifier">T</span><span class="special">&&</span> <span class="keyword">operator</span> <span class="special">*()</span> <span class="special">&&;</span> <a class="link" href="detailed_semantics.html#reference_optional_operator_asterisk"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">value</span><span class="special">()</span> <span class="keyword">const</span><span class="special">&</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_value"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
<span class="identifier">T</span><span class="special">&</span> <span class="identifier">value</span><span class="special">()</span> <span class="special">&</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_value"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
<span class="identifier">T</span><span class="special">&&</span> <span class="identifier">value</span><span class="special">()</span> <span class="special">&&</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_value"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">></span> <span class="identifier">T</span> <span class="identifier">value_or</span><span class="special">(</span> <span class="identifier">U</span> <span class="special">&&</span> <span class="identifier">v</span> <span class="special">)</span> <span class="keyword">const</span><span class="special">&</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_value_or"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">></span> <span class="identifier">T</span> <span class="identifier">value_or</span><span class="special">(</span> <span class="identifier">U</span> <span class="special">&&</span> <span class="identifier">v</span> <span class="special">)</span> <span class="special">&&</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_value_or"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="identifier">T</span> <span class="keyword">const</span><span class="special">*</span> <span class="identifier">get_ptr</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_get_ptr"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
<span class="identifier">T</span><span class="special">*</span> <span class="identifier">get_ptr</span><span class="special">()</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_get_ptr"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="keyword">explicit</span> <span class="keyword">operator</span> <span class="keyword">bool</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_operator_bool"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="keyword">bool</span> <span class="keyword">operator</span><span class="special">!()</span> <span class="keyword">const</span> <span class="keyword">noexcept</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_operator_not"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="comment">// deprecated methods</span>
|
||||
|
||||
<span class="comment">// (deprecated)</span>
|
||||
<span class="keyword">void</span> <span class="identifier">reset</span><span class="special">()</span> <span class="keyword">noexcept</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_reset"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="comment">// (deprecated)</span>
|
||||
<span class="keyword">void</span> <span class="identifier">reset</span> <span class="special">(</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_reset_value"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="comment">// (deprecated)</span>
|
||||
<span class="keyword">bool</span> <span class="identifier">is_initialized</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_is_initialized"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="comment">// (deprecated)</span>
|
||||
<span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">get_value_or</span><span class="special">(</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="keyword">default</span> <span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_get_value_or_value"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
<span class="special">};</span>
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> <span class="keyword">inline</span> <span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">==</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">y</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_operator_compare_equal_optional_optional"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> <span class="keyword">inline</span> <span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">!=</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">y</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_operator_compare_not_equal_optional_optional"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> <span class="keyword">inline</span> <span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special"><</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">y</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_operator_compare_less_optional_optional"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> <span class="keyword">inline</span> <span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">></span> <span class="special">(</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">y</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_operator_compare_greater_optional_optional"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> <span class="keyword">inline</span> <span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special"><=</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">y</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_operator_compare_less_or_equal_optional_optional"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> <span class="keyword">inline</span> <span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">>=</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">y</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_operator_compare_greater_or_equal_optional_optional"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> <span class="keyword">inline</span> <span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">==</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">none_t</span> <span class="special">)</span> <span class="keyword">noexcept</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_operator_compare_equal_optional_none"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> <span class="keyword">inline</span> <span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">!=</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">none_t</span> <span class="special">)</span> <span class="keyword">noexcept</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_operator_compare_not_equal_optional_none"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> <span class="keyword">inline</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="identifier">make_optional</span> <span class="special">(</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">v</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_make_optional_value"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> <span class="keyword">inline</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="identifier">make_optional</span> <span class="special">(</span> <span class="keyword">bool</span> <span class="identifier">condition</span><span class="special">,</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">v</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_make_optional_bool_value"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> <span class="keyword">inline</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">get_optional_value_or</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">opt</span><span class="special">,</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="keyword">default</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_get_value_or_value"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> <span class="keyword">inline</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">get</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">opt</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_get"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> <span class="keyword">inline</span> <span class="identifier">T</span><span class="special">&</span> <span class="identifier">get</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span> <span class="identifier">opt</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_get"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> <span class="keyword">inline</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">*</span> <span class="identifier">get</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">const</span><span class="special">*</span> <span class="identifier">opt</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_get"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> <span class="keyword">inline</span> <span class="identifier">T</span><span class="special">*</span> <span class="identifier">get</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">>*</span> <span class="identifier">opt</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_get"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> <span class="keyword">inline</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">*</span> <span class="identifier">get_pointer</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">opt</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_get_ptr"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> <span class="keyword">inline</span> <span class="identifier">T</span><span class="special">*</span> <span class="identifier">get_pointer</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="special">&</span> <span class="identifier">opt</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_get_ptr"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> <span class="keyword">inline</span> <span class="keyword">void</span> <span class="identifier">swap</span><span class="special">(</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">>&</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">>&</span> <span class="identifier">y</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_swap_optional_optional"><span class="inlinemediaobject"><img src="../../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="special">}</span> <span class="comment">// namespace boost</span>
|
||||
</pre>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014 Andrzej Krzemieński<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
</div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="../../optional/reference.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../../optional/reference.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="detailed_semantics.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -6,7 +6,7 @@
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||
<link rel="home" href="../index.html" title="Chapter 1. Boost.Optional">
|
||||
<link rel="up" href="../index.html" title="Chapter 1. Boost.Optional">
|
||||
<link rel="prev" href="development.html" title="Development">
|
||||
<link rel="prev" href="tutorial/type_requirements.html" title="Type requirements">
|
||||
<link rel="next" href="detailed_semantics.html" title="Detailed Semantics">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
@ -20,7 +20,7 @@
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="development.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="detailed_semantics.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
<a accesskey="p" href="tutorial/type_requirements.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="detailed_semantics.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
@ -74,6 +74,8 @@
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">></span> <span class="identifier">optional</span><span class="special">&</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">U</span><span class="special">>&&</span> <span class="identifier">rhs</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_operator_move_equal_other_optional"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span><span class="special">...</span> <span class="identifier">Args</span><span class="special">></span> <span class="keyword">void</span> <span class="identifier">emplace</span> <span class="special">(</span> <span class="identifier">Args</span><span class="special">...&&</span> <span class="identifier">args</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_emplace"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">InPlaceFactory</span><span class="special">></span> <span class="identifier">optional</span><span class="special">&</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span> <span class="identifier">InPlaceFactory</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">f</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_operator_equal_factory"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">TypedInPlaceFactory</span><span class="special">></span> <span class="identifier">optional</span><span class="special">&</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span> <span class="identifier">TypedInPlaceFactory</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">f</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_operator_equal_factory"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
|
||||
@ -81,14 +83,19 @@
|
||||
<span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">get</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_get"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
|
||||
<span class="identifier">T</span><span class="special">&</span> <span class="identifier">get</span><span class="special">()</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_get"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="comment">// [new in 1.34]</span>
|
||||
<span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">get_value_or</span><span class="special">(</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="keyword">default</span> <span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_get_value_or_value"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="identifier">T</span> <span class="keyword">const</span><span class="special">*</span> <span class="keyword">operator</span> <span class="special">->()</span> <span class="keyword">const</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_operator_arrow"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
|
||||
<span class="identifier">T</span><span class="special">*</span> <span class="keyword">operator</span> <span class="special">->()</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_operator_arrow"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="keyword">operator</span> <span class="special">*()</span> <span class="keyword">const</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_get"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
|
||||
<span class="identifier">T</span><span class="special">&</span> <span class="keyword">operator</span> <span class="special">*()</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_get"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
|
||||
<span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="keyword">operator</span> <span class="special">*()</span> <span class="keyword">const</span><span class="special">&</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_operator_asterisk"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
|
||||
<span class="identifier">T</span><span class="special">&</span> <span class="keyword">operator</span> <span class="special">*()</span> <span class="special">&;</span> <a class="link" href="detailed_semantics.html#reference_optional_operator_asterisk"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
|
||||
<span class="identifier">T</span><span class="special">&&</span> <span class="keyword">operator</span> <span class="special">*()</span> <span class="special">&&;</span> <a class="link" href="detailed_semantics.html#reference_optional_operator_asterisk"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">value</span><span class="special">()</span> <span class="keyword">const</span><span class="special">&</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_value"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
|
||||
<span class="identifier">T</span><span class="special">&</span> <span class="identifier">value</span><span class="special">()</span> <span class="special">&</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_value"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
|
||||
<span class="identifier">T</span><span class="special">&&</span> <span class="identifier">value</span><span class="special">()</span> <span class="special">&&</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_value"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">></span> <span class="identifier">T</span> <span class="identifier">value_or</span><span class="special">(</span> <span class="identifier">U</span> <span class="special">&&</span> <span class="identifier">v</span> <span class="special">)</span> <span class="keyword">const</span><span class="special">&</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_value_or"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">></span> <span class="identifier">T</span> <span class="identifier">value_or</span><span class="special">(</span> <span class="identifier">U</span> <span class="special">&&</span> <span class="identifier">v</span> <span class="special">)</span> <span class="special">&&</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_value_or"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="identifier">T</span> <span class="keyword">const</span><span class="special">*</span> <span class="identifier">get_ptr</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_get_ptr"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
|
||||
<span class="identifier">T</span><span class="special">*</span> <span class="identifier">get_ptr</span><span class="special">()</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_get_ptr"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
|
||||
@ -108,6 +115,8 @@
|
||||
<span class="comment">// (deprecated)</span>
|
||||
<span class="keyword">bool</span> <span class="identifier">is_initialized</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_is_initialized"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="comment">// (deprecated)</span>
|
||||
<span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">get_value_or</span><span class="special">(</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="keyword">default</span> <span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_get_value_or_value"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
|
||||
<span class="special">};</span>
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> <span class="keyword">inline</span> <span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">==</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">y</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_operator_compare_equal_optional_optional"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
|
||||
@ -126,13 +135,10 @@
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> <span class="keyword">inline</span> <span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">!=</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">none_t</span> <span class="special">)</span> <span class="keyword">noexcept</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_operator_compare_not_equal_optional_none"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="comment">// [new in 1.34]</span>
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> <span class="keyword">inline</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="identifier">make_optional</span> <span class="special">(</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">v</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_make_optional_value"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="comment">// [new in 1.34]</span>
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> <span class="keyword">inline</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="identifier">make_optional</span> <span class="special">(</span> <span class="keyword">bool</span> <span class="identifier">condition</span><span class="special">,</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">v</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_make_optional_bool_value"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="comment">// [new in 1.34]</span>
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> <span class="keyword">inline</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">get_optional_value_or</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">opt</span><span class="special">,</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="keyword">default</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_get_value_or_value"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">></span> <span class="keyword">inline</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">get</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">opt</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="detailed_semantics.html#reference_optional_get"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
|
||||
@ -162,7 +168,7 @@
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="development.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="detailed_semantics.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
<a accesskey="p" href="tutorial/type_requirements.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="detailed_semantics.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
523
doc/html/boost_optional/tutorial.html
Normal file
523
doc/html/boost_optional/tutorial.html
Normal file
@ -0,0 +1,523 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Tutorial</title>
|
||||
<link rel="stylesheet" href="../../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||
<link rel="home" href="../index.html" title="Chapter 1. Boost.Optional">
|
||||
<link rel="up" href="../index.html" title="Chapter 1. Boost.Optional">
|
||||
<link rel="prev" href="quick_start.html" title="Quick Start">
|
||||
<link rel="next" href="synopsis.html" title="Synopsis">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="quick_start.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="synopsis.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
|
||||
<a name="boost_optional.tutorial"></a><a class="link" href="tutorial.html" title="Tutorial">Tutorial</a>
|
||||
</h2></div></div></div>
|
||||
<div class="toc"><dl class="toc">
|
||||
<dt><span class="section"><a href="tutorial.html#boost_optional.tutorial.motivation">Motivation</a></span></dt>
|
||||
<dt><span class="section"><a href="tutorial.html#boost_optional.tutorial.design_overview">Design Overview</a></span></dt>
|
||||
</dl></div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_optional.tutorial.motivation"></a><a class="link" href="tutorial.html#boost_optional.tutorial.motivation" title="Motivation">Motivation</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
Consider these functions which should return a value but which might not
|
||||
have a value to return:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
(A) <code class="computeroutput"><span class="keyword">double</span> <span class="identifier">sqrt</span><span class="special">(</span><span class="keyword">double</span> <span class="identifier">n</span> <span class="special">);</span></code>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
(B) <code class="computeroutput"><span class="keyword">char</span> <span class="identifier">get_async_input</span><span class="special">();</span></code>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
(C) <code class="computeroutput"><span class="identifier">point</span> <span class="identifier">polygon</span><span class="special">::</span><span class="identifier">get_any_point_effectively_inside</span><span class="special">();</span></code>
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
There are different approaches to the issue of not having a value to return.
|
||||
</p>
|
||||
<p>
|
||||
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 assert 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.
|
||||
</p>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
<p>
|
||||
A similar situation occurs with function (C): it is conceptually an error
|
||||
to ask a <span class="emphasis"><em>null-area</em></span> 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.
|
||||
</p>
|
||||
<p>
|
||||
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 <code class="computeroutput"><span class="identifier">EOF</span></code>, <code class="computeroutput"><span class="identifier">string</span><span class="special">::</span><span class="identifier">npos</span></code>,
|
||||
points at infinity, etc...
|
||||
</p>
|
||||
<p>
|
||||
When those values exist, i.e. the return type can hold all meaningful values
|
||||
<span class="emphasis"><em>plus</em></span> the <span class="emphasis"><em>signal</em></span> 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 <code class="computeroutput"><span class="keyword">int</span></code>
|
||||
in place of <code class="computeroutput"><span class="keyword">char</span></code>; or a compound
|
||||
type, such as <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="identifier">point</span><span class="special">,</span><span class="keyword">bool</span><span class="special">></span></code>.
|
||||
</p>
|
||||
<p>
|
||||
Returning a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span><span class="keyword">bool</span><span class="special">></span></code>, 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:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="keyword">char</span><span class="special">,</span><span class="keyword">bool</span><span class="special">></span> <span class="identifier">get_async_input</span><span class="special">();</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="identifier">point</span><span class="special">,</span><span class="keyword">bool</span><span class="special">></span> <span class="identifier">polygon</span><span class="special">::</span><span class="identifier">get_any_point_effectively_inside</span><span class="special">();</span>
|
||||
</pre>
|
||||
<p>
|
||||
These functions use a consistent interface for dealing with possibly nonexistent
|
||||
results:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="identifier">point</span><span class="special">,</span><span class="keyword">bool</span><span class="special">></span> <span class="identifier">p</span> <span class="special">=</span> <span class="identifier">poly</span><span class="special">.</span><span class="identifier">get_any_point_effectively_inside</span><span class="special">();</span>
|
||||
<span class="keyword">if</span> <span class="special">(</span> <span class="identifier">p</span><span class="special">.</span><span class="identifier">second</span> <span class="special">)</span>
|
||||
<span class="identifier">flood_fill</span><span class="special">(</span><span class="identifier">p</span><span class="special">.</span><span class="identifier">first</span><span class="special">);</span>
|
||||
</pre>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
<p>
|
||||
Clearly, we need a better idiom.
|
||||
</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_optional.tutorial.design_overview"></a><a class="link" href="tutorial.html#boost_optional.tutorial.design_overview" title="Design Overview">Design Overview</a>
|
||||
</h3></div></div></div>
|
||||
<div class="toc"><dl class="toc">
|
||||
<dt><span class="section"><a href="tutorial.html#boost_optional.tutorial.design_overview.the_models">The
|
||||
models</a></span></dt>
|
||||
<dt><span class="section"><a href="tutorial.html#boost_optional.tutorial.design_overview.the_semantics">The
|
||||
semantics</a></span></dt>
|
||||
<dt><span class="section"><a href="tutorial.html#boost_optional.tutorial.design_overview.the_interface">The
|
||||
Interface</a></span></dt>
|
||||
</dl></div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h4 class="title">
|
||||
<a name="boost_optional.tutorial.design_overview.the_models"></a><a class="link" href="tutorial.html#boost_optional.tutorial.design_overview.the_models" title="The models">The
|
||||
models</a>
|
||||
</h4></div></div></div>
|
||||
<p>
|
||||
In C++, we can <span class="emphasis"><em>declare</em></span> an object (a variable) of type
|
||||
<code class="computeroutput"><span class="identifier">T</span></code>, and we can give this
|
||||
variable an <span class="emphasis"><em>initial value</em></span> (through an <span class="emphasis"><em>initializer</em></span>.
|
||||
(cf. 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 <span class="bold"><strong>uninitialized</strong></span>. Its actual value exist
|
||||
but has an <span class="emphasis"><em>indeterminate initial value</em></span> (cf. 8.5/11).
|
||||
<code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>
|
||||
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 <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code> and no initial value is given, the
|
||||
variable is <span class="emphasis"><em>formally</em></span> uninitialized. A formally uninitialized
|
||||
optional object has conceptually no value at all and this situation can
|
||||
be tested at runtime. It is formally <span class="emphasis"><em>undefined behavior</em></span>
|
||||
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
|
||||
<span class="emphasis"><em>uninitialized</em></span>.
|
||||
</p>
|
||||
<p>
|
||||
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: <code class="computeroutput"><span class="identifier">EOF</span></code>,
|
||||
<code class="computeroutput"><span class="identifier">npos</span></code>, -1, etc... This is
|
||||
equivalent to adding the special value to the set of possible values of
|
||||
a given type. This super set of <code class="computeroutput"><span class="identifier">T</span></code>
|
||||
plus some <span class="emphasis"><em>nil_t</em></span>—where <code class="computeroutput"><span class="identifier">nil_t</span></code>
|
||||
is some stateless POD—can be modeled in modern languages as a <span class="bold"><strong>discriminated union</strong></span> of T and nil_t. Discriminated
|
||||
unions are often called <span class="emphasis"><em>variants</em></span>. A variant has a
|
||||
<span class="emphasis"><em>current type</em></span>, which in our case is either <code class="computeroutput"><span class="identifier">T</span></code> or <code class="computeroutput"><span class="identifier">nil_t</span></code>.
|
||||
Using the <a href="../../../../variant/index.html" target="_top">Boost.Variant</a>
|
||||
library, this model can be implemented in terms of <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">variant</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span><span class="identifier">nil_t</span><span class="special">></span></code>. There is precedent for a discriminated
|
||||
union as a model for an optional value: the <a href="http://www.haskell.org/" target="_top">Haskell</a>
|
||||
<span class="bold"><strong>Maybe</strong></span> built-in type constructor. Thus,
|
||||
a discriminated union <code class="computeroutput"><span class="identifier">T</span><span class="special">+</span><span class="identifier">nil_t</span></code>
|
||||
serves as a conceptual foundation.
|
||||
</p>
|
||||
<p>
|
||||
A <code class="computeroutput"><span class="identifier">variant</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span><span class="identifier">nil_t</span><span class="special">></span></code> follows naturally from the traditional
|
||||
idiom of extending the range of possible values adding an additional sentinel
|
||||
value with the special meaning of <span class="emphasis"><em>Nothing</em></span>. However,
|
||||
this additional <span class="emphasis"><em>Nothing</em></span> 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.
|
||||
</p>
|
||||
<p>
|
||||
The observation made in the last paragraph about the irrelevant nature
|
||||
of the additional <code class="computeroutput"><span class="identifier">nil_t</span></code>
|
||||
with respect to <span class="underline">purpose</span> of <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>
|
||||
suggests an alternative model: a <span class="emphasis"><em>container</em></span> that either
|
||||
has a value of <code class="computeroutput"><span class="identifier">T</span></code> or nothing.
|
||||
</p>
|
||||
<p>
|
||||
As of this writing I don't know of any precedent 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.
|
||||
</p>
|
||||
<p>
|
||||
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
|
||||
<span class="emphasis"><em>exact</em></span> semantics required for a wrapper of optional
|
||||
values:
|
||||
</p>
|
||||
<p>
|
||||
Discriminated-union:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>deep-copy</strong></span> semantics: copies of the
|
||||
variant implies copies of the value.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>deep-relational</strong></span> semantics: comparisons
|
||||
between variants matches both current types and values
|
||||
</li>
|
||||
<li class="listitem">
|
||||
If the variant's current type is <code class="computeroutput"><span class="identifier">T</span></code>,
|
||||
it is modeling an <span class="emphasis"><em>initialized</em></span> optional.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
If the variant's current type is not <code class="computeroutput"><span class="identifier">T</span></code>,
|
||||
it is modeling an <span class="emphasis"><em>uninitialized</em></span> optional.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
Testing if the variant's current type is <code class="computeroutput"><span class="identifier">T</span></code>
|
||||
models testing if the optional is initialized
|
||||
</li>
|
||||
<li class="listitem">
|
||||
Trying to extract a <code class="computeroutput"><span class="identifier">T</span></code>
|
||||
from a variant when its current type is not <code class="computeroutput"><span class="identifier">T</span></code>,
|
||||
models the undefined behavior of trying to access the value of an uninitialized
|
||||
optional
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
Single-element container:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>deep-copy</strong></span> semantics: copies of the
|
||||
container implies copies of the value.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>deep-relational</strong></span> semantics: comparisons
|
||||
between containers compare container size and if match, contained value
|
||||
</li>
|
||||
<li class="listitem">
|
||||
If the container is not empty (contains an object of type <code class="computeroutput"><span class="identifier">T</span></code>), it is modeling an <span class="emphasis"><em>initialized</em></span>
|
||||
optional.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
If the container is empty, it is modeling an <span class="emphasis"><em>uninitialized</em></span>
|
||||
optional.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
Testing if the container is empty models testing if the optional is
|
||||
initialized
|
||||
</li>
|
||||
<li class="listitem">
|
||||
Trying to extract a <code class="computeroutput"><span class="identifier">T</span></code>
|
||||
from an empty container models the undefined behavior of trying to
|
||||
access the value of an uninitialized optional
|
||||
</li>
|
||||
</ul></div>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h4 class="title">
|
||||
<a name="boost_optional.tutorial.design_overview.the_semantics"></a><a class="link" href="tutorial.html#boost_optional.tutorial.design_overview.the_semantics" title="The semantics">The
|
||||
semantics</a>
|
||||
</h4></div></div></div>
|
||||
<p>
|
||||
Objects of type <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code> are intended to be used in places where
|
||||
objects of type <code class="computeroutput"><span class="identifier">T</span></code> would
|
||||
but which might be uninitialized. Hence, <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>'s purpose is to formalize the additional
|
||||
possibly uninitialized state. From the perspective of this role, <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>
|
||||
can have the same operational semantics of <code class="computeroutput"><span class="identifier">T</span></code>
|
||||
plus the additional semantics corresponding to this special state. As such,
|
||||
<code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>
|
||||
could be thought of as a <span class="emphasis"><em>supertype</em></span> of <code class="computeroutput"><span class="identifier">T</span></code>. 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 <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code> a <span class="emphasis"><em>subtype</em></span> of
|
||||
<code class="computeroutput"><span class="identifier">T</span></code> 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.
|
||||
</p>
|
||||
<p>
|
||||
We can draw from the purpose of <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code> the required basic semantics:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Default Construction:</strong></span> To introduce
|
||||
a formally uninitialized wrapped object.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Direct Value Construction via copy:</strong></span>
|
||||
To introduce a formally initialized wrapped object whose value is obtained
|
||||
as a copy of some object.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Deep Copy Construction:</strong></span> To obtain
|
||||
a new yet equivalent wrapped object.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Direct Value Assignment (upon initialized):</strong></span>
|
||||
To assign a value to the wrapped object.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Direct Value Assignment (upon uninitialized):</strong></span>
|
||||
To initialize the wrapped object with a value obtained as a copy of
|
||||
some object.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Assignment (upon initialized):</strong></span> To
|
||||
assign to the wrapped object the value of another wrapped object.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Assignment (upon uninitialized):</strong></span> To
|
||||
initialize the wrapped object with value of another wrapped object.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Deep Relational Operations (when supported by
|
||||
the type T):</strong></span> To compare wrapped object values taking into
|
||||
account the presence of uninitialized states.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Value access:</strong></span> To unwrap the wrapped
|
||||
object.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Initialization state query:</strong></span> To determine
|
||||
if the object is formally initialized or not.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Swap:</strong></span> To exchange wrapped objects.
|
||||
(with whatever exception safety guarantees are provided by <code class="computeroutput"><span class="identifier">T</span></code>'s swap).
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>De-initialization:</strong></span> To release the
|
||||
wrapped object (if any) and leave the wrapper in the uninitialized
|
||||
state.
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h4 class="title">
|
||||
<a name="boost_optional.tutorial.design_overview.the_interface"></a><a class="link" href="tutorial.html#boost_optional.tutorial.design_overview.the_interface" title="The Interface">The
|
||||
Interface</a>
|
||||
</h4></div></div></div>
|
||||
<p>
|
||||
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 <code class="computeroutput"><span class="identifier">T</span></code> type
|
||||
as much as possible. In order to choose the proper degree of adoption of
|
||||
the native <code class="computeroutput"><span class="identifier">T</span></code> interface,
|
||||
the following must be noted: Even if all the operations supported by an
|
||||
instance of type <code class="computeroutput"><span class="identifier">T</span></code> are
|
||||
defined for the entire range of values for such a type, an <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>
|
||||
extends such a set of values with a new value for which most (otherwise
|
||||
valid) operations are not defined in terms of <code class="computeroutput"><span class="identifier">T</span></code>.
|
||||
</p>
|
||||
<p>
|
||||
Furthermore, since <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code> itself is merely a <code class="computeroutput"><span class="identifier">T</span></code>
|
||||
wrapper (modeling a <code class="computeroutput"><span class="identifier">T</span></code> supertype),
|
||||
any attempt to define such operations upon uninitialized optionals will
|
||||
be totally artificial w.r.t. <code class="computeroutput"><span class="identifier">T</span></code>.
|
||||
</p>
|
||||
<p>
|
||||
This library chooses an interface which follows from <code class="computeroutput"><span class="identifier">T</span></code>'s
|
||||
interface only for those operations which are well defined (w.r.t the type
|
||||
<code class="computeroutput"><span class="identifier">T</span></code>) even if any of the operands
|
||||
are uninitialized. These operations include: construction, copy-construction,
|
||||
assignment, swap and relational operations.
|
||||
</p>
|
||||
<p>
|
||||
For the value access operations, which are undefined (w.r.t the type <code class="computeroutput"><span class="identifier">T</span></code>) when the operand is uninitialized,
|
||||
a different interface is chosen (which will be explained next).
|
||||
</p>
|
||||
<p>
|
||||
Also, the presence of the possibly uninitialized state requires additional
|
||||
operations not provided by <code class="computeroutput"><span class="identifier">T</span></code>
|
||||
itself which are supported by a special interface.
|
||||
</p>
|
||||
<h6>
|
||||
<a name="boost_optional.tutorial.design_overview.the_interface.h0"></a>
|
||||
<span class="phrase"><a name="boost_optional.tutorial.design_overview.the_interface.lexically_hinted_value_access_in_the_presence_of_possibly_untitialized_optional_objects__the_operators___and___gt_"></a></span><a class="link" href="tutorial.html#boost_optional.tutorial.design_overview.the_interface.lexically_hinted_value_access_in_the_presence_of_possibly_untitialized_optional_objects__the_operators___and___gt_">Lexically-hinted
|
||||
Value Access in the presence of possibly untitialized optional objects:
|
||||
The operators * and -></a>
|
||||
</h6>
|
||||
<p>
|
||||
A relevant feature of a pointer is that it can have a <span class="bold"><strong>null
|
||||
pointer value</strong></span>. This is a <span class="emphasis"><em>special</em></span> 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 nonexistent
|
||||
objects.
|
||||
</p>
|
||||
<p>
|
||||
This meaning of the null pointer value allowed pointers to became a <span class="emphasis"><em>de
|
||||
facto</em></span> 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 <span class="emphasis"><em>refer</em></span>
|
||||
to optional (that is, possibly nonexistent) objects; particularly as optional
|
||||
arguments to a function, but also quite often as optional data members.
|
||||
</p>
|
||||
<p>
|
||||
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: <code class="computeroutput"><span class="special">(</span>
|
||||
<span class="special">*</span><span class="identifier">p</span>
|
||||
<span class="special">=</span> <span class="number">2</span> <span class="special">)</span></code> and <code class="computeroutput"><span class="special">(</span>
|
||||
<span class="identifier">p</span><span class="special">-></span><span class="identifier">foo</span><span class="special">()</span> <span class="special">)</span></code>, implicitly convey the notion of optionality,
|
||||
and this information is tied to the <span class="emphasis"><em>syntax</em></span> of the
|
||||
expressions. That is, the presence of operators <code class="computeroutput"><span class="special">*</span></code>
|
||||
and <code class="computeroutput"><span class="special">-></span></code> tell by themselves
|
||||
—without any additional context— that the expression will be undefined
|
||||
unless the implied pointee actually exist.
|
||||
</p>
|
||||
<p>
|
||||
Such a <span class="emphasis"><em>de facto</em></span> idiom for referring to optional objects
|
||||
can be formalized in the form of a concept: the <a href="../../../../utility/OptionalPointee.html" target="_top">OptionalPointee</a>
|
||||
concept. This concept captures the syntactic usage of operators <code class="computeroutput"><span class="special">*</span></code>, <code class="computeroutput"><span class="special">-></span></code>
|
||||
and contextual conversion to <code class="computeroutput"><span class="keyword">bool</span></code>
|
||||
to convey the notion of optionality.
|
||||
</p>
|
||||
<p>
|
||||
However, pointers are good to <span class="underline">refer</span>
|
||||
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.
|
||||
</p>
|
||||
<p>
|
||||
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 <code class="computeroutput"><span class="identifier">X</span></code>, it can use <code class="computeroutput"><span class="identifier">shared_ptr</span><span class="special"><</span><span class="identifier">X</span><span class="special">></span></code>
|
||||
as the return value. However, this requires dynamic allocation of <code class="computeroutput"><span class="identifier">X</span></code>. If <code class="computeroutput"><span class="identifier">X</span></code>
|
||||
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
|
||||
<a href="../../../../utility/OptionalPointee.html" target="_top">OptionalPointee</a>
|
||||
concept incarnated by pointers.
|
||||
</p>
|
||||
<h6>
|
||||
<a name="boost_optional.tutorial.design_overview.the_interface.h1"></a>
|
||||
<span class="phrase"><a name="boost_optional.tutorial.design_overview.the_interface.optional_lt_t_gt__as_a_model_of_optionalpointee"></a></span><a class="link" href="tutorial.html#boost_optional.tutorial.design_overview.the_interface.optional_lt_t_gt__as_a_model_of_optionalpointee">Optional<T>
|
||||
as a model of OptionalPointee</a>
|
||||
</h6>
|
||||
<p>
|
||||
For value access operations <code class="computeroutput"><span class="identifier">optional</span><span class="special"><></span></code> uses operators <code class="computeroutput"><span class="special">*</span></code>
|
||||
and <code class="computeroutput"><span class="special">-></span></code> to lexically warn
|
||||
about the possibly uninitialized state appealing to the familiar pointer
|
||||
semantics w.r.t. to null pointers.
|
||||
</p>
|
||||
<div class="warning"><table border="0" summary="Warning">
|
||||
<tr>
|
||||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Warning]" src="../../../../../doc/src/images/warning.png"></td>
|
||||
<th align="left">Warning</th>
|
||||
</tr>
|
||||
<tr><td align="left" valign="top"><p>
|
||||
However, it is particularly important to note that <code class="computeroutput"><span class="identifier">optional</span><span class="special"><></span></code> objects are not pointers. <span class="underline"><code class="computeroutput"><span class="identifier">optional</span><span class="special"><></span></code> is not, and does not model, a
|
||||
pointer</span>.
|
||||
</p></td></tr>
|
||||
</table></div>
|
||||
<p>
|
||||
For instance, <code class="computeroutput"><span class="identifier">optional</span><span class="special"><></span></code> does not have shallow-copy so does
|
||||
not alias: two different optionals never refer to the <span class="emphasis"><em>same</em></span>
|
||||
value unless <code class="computeroutput"><span class="identifier">T</span></code> itself is
|
||||
a reference (but may have <span class="emphasis"><em>equivalent</em></span> values). The
|
||||
difference between an <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code> and a pointer must be kept in mind,
|
||||
particularly because the semantics of relational operators are different:
|
||||
since <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>
|
||||
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 <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>
|
||||
by <code class="computeroutput"><span class="identifier">T</span><span class="special">*</span></code>
|
||||
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 <a href="../../../../utility/OptionalPointee.html#equal" target="_top"><code class="computeroutput"><span class="identifier">equal_pointees</span><span class="special">()</span></code></a>
|
||||
and <a href="../../../../utility/OptionalPointee.html#less" target="_top"><code class="computeroutput"><span class="identifier">less_pointees</span><span class="special">()</span></code></a>
|
||||
instead.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014 Andrzej Krzemieński<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
</div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="quick_start.html"><img src="../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../index.html"><img src="../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../index.html"><img src="../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="synopsis.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,108 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>A note about optional<bool></title>
|
||||
<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||
<link rel="home" href="../../index.html" title="Boost.Optional">
|
||||
<link rel="up" href="../../optional/tutorial.html" title="Tutorial">
|
||||
<link rel="prev" href="in_place_factories.html" title="In-Place Factories">
|
||||
<link rel="next" href="exception_safety_guarantees.html" title="Exception Safety Guarantees">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="in_place_factories.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../../optional/tutorial.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="exception_safety_guarantees.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_optional.tutorial.a_note_about_optional_bool_"></a><a class="link" href="a_note_about_optional_bool_.html" title="A note about optional<bool>">A
|
||||
note about optional<bool></a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
<code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="keyword">bool</span><span class="special">></span></code> should
|
||||
be used with special caution and consideration.
|
||||
</p>
|
||||
<p>
|
||||
First, it is functionally similar to a tristate boolean (false, maybe, true)
|
||||
—such as <a href="../../../../../../doc/html/tribool.html" target="_top">boost::tribool</a>—
|
||||
except that in a tristate boolean, the maybe state <span class="underline">represents
|
||||
a valid value</span>, unlike the corresponding state of an uninitialized
|
||||
<code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="keyword">bool</span><span class="special">></span></code>.
|
||||
It should be carefully considered if an <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="keyword">bool</span><span class="special">></span></code>
|
||||
instead of a <code class="computeroutput"><span class="identifier">tribool</span></code> is really
|
||||
needed.
|
||||
</p>
|
||||
<p>
|
||||
Second, although <code class="computeroutput"><span class="identifier">optional</span><span class="special"><></span></code> provides a contextual conversion
|
||||
to <code class="computeroutput"><span class="keyword">bool</span></code> in C++11, this falls
|
||||
back to an implicit conversion on older compilers. This conversion refers
|
||||
to the initialization state and not to the contained value. Using <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="keyword">bool</span><span class="special">></span></code> can
|
||||
lead to subtle errors due to the implicit <code class="computeroutput"><span class="keyword">bool</span></code>
|
||||
conversion:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">void</span> <span class="identifier">foo</span> <span class="special">(</span> <span class="keyword">bool</span> <span class="identifier">v</span> <span class="special">)</span> <span class="special">;</span>
|
||||
<span class="keyword">void</span> <span class="identifier">bar</span><span class="special">()</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">optional</span><span class="special"><</span><span class="keyword">bool</span><span class="special">></span> <span class="identifier">v</span> <span class="special">=</span> <span class="keyword">try</span><span class="special">();</span>
|
||||
|
||||
<span class="comment">// The following intended to pass the value of 'v' to foo():</span>
|
||||
<span class="identifier">foo</span><span class="special">(</span><span class="identifier">v</span><span class="special">);</span>
|
||||
<span class="comment">// But instead, the initialization state is passed</span>
|
||||
<span class="comment">// due to a typo: it should have been foo(*v).</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
The only implicit conversion is to <code class="computeroutput"><span class="keyword">bool</span></code>,
|
||||
and it is safe in the sense that typical integral promotions don't apply
|
||||
(i.e. if <code class="computeroutput"><span class="identifier">foo</span><span class="special">()</span></code>
|
||||
takes an <code class="computeroutput"><span class="keyword">int</span></code> instead, it won't
|
||||
compile).
|
||||
</p>
|
||||
<p>
|
||||
Third, mixed comparisons with <code class="computeroutput"><span class="keyword">bool</span></code>
|
||||
work differently than similar mixed comparisons between pointers and <code class="computeroutput"><span class="keyword">bool</span></code>, so the results might surprise you:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">optional</span><span class="special"><</span><span class="keyword">bool</span><span class="special">></span> <span class="identifier">oEmpty</span><span class="special">(</span><span class="identifier">none</span><span class="special">),</span> <span class="identifier">oTrue</span><span class="special">(</span><span class="keyword">true</span><span class="special">),</span> <span class="identifier">oFalse</span><span class="special">(</span><span class="keyword">false</span><span class="special">);</span>
|
||||
|
||||
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">oEmpty</span> <span class="special">==</span> <span class="identifier">none</span><span class="special">);</span> <span class="comment">// renders true</span>
|
||||
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">oEmpty</span> <span class="special">==</span> <span class="keyword">false</span><span class="special">);</span> <span class="comment">// renders false!</span>
|
||||
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">oEmpty</span> <span class="special">==</span> <span class="keyword">true</span><span class="special">);</span> <span class="comment">// renders false!</span>
|
||||
|
||||
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">oFalse</span> <span class="special">==</span> <span class="identifier">none</span><span class="special">);</span> <span class="comment">// renders false</span>
|
||||
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">oFalse</span> <span class="special">==</span> <span class="keyword">false</span><span class="special">);</span> <span class="comment">// renders true!</span>
|
||||
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">oFalse</span> <span class="special">==</span> <span class="keyword">true</span><span class="special">);</span> <span class="comment">// renders false</span>
|
||||
|
||||
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">oTrue</span> <span class="special">==</span> <span class="identifier">none</span><span class="special">);</span> <span class="comment">// renders false</span>
|
||||
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">oTrue</span> <span class="special">==</span> <span class="keyword">false</span><span class="special">);</span> <span class="comment">// renders false</span>
|
||||
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">oTrue</span> <span class="special">==</span> <span class="keyword">true</span><span class="special">);</span> <span class="comment">// renders true</span>
|
||||
</pre>
|
||||
<p>
|
||||
In other words, for <code class="computeroutput"><span class="identifier">optional</span><span class="special"><></span></code>, the following assertion does not
|
||||
hold:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">assert</span><span class="special">((</span><span class="identifier">opt</span> <span class="special">==</span> <span class="keyword">false</span><span class="special">)</span> <span class="special">==</span> <span class="special">(!</span><span class="identifier">opt</span><span class="special">));</span>
|
||||
</pre>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014 Andrzej Krzemieński<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
</div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="in_place_factories.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../../optional/tutorial.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="exception_safety_guarantees.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
184
doc/html/boost_optional/tutorial/design_overview.html
Normal file
184
doc/html/boost_optional/tutorial/design_overview.html
Normal file
@ -0,0 +1,184 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Design Overview</title>
|
||||
<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||
<link rel="home" href="../../index.html" title="Boost.Optional">
|
||||
<link rel="up" href="../../optional/tutorial.html" title="Tutorial">
|
||||
<link rel="prev" href="../../optional/tutorial.html" title="Tutorial">
|
||||
<link rel="next" href="design_overview/the_semantics.html" title="The semantics">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="../../optional/tutorial.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../../optional/tutorial.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="design_overview/the_semantics.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_optional.tutorial.design_overview"></a><a class="link" href="design_overview.html" title="Design Overview">Design Overview</a>
|
||||
</h3></div></div></div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h4 class="title">
|
||||
<a name="boost_optional.tutorial.design_overview.the_models"></a><a class="link" href="design_overview.html#boost_optional.tutorial.design_overview.the_models" title="The models">The
|
||||
models</a>
|
||||
</h4></div></div></div>
|
||||
<p>
|
||||
In C++, we can <span class="emphasis"><em>declare</em></span> an object (a variable) of type
|
||||
<code class="computeroutput"><span class="identifier">T</span></code>, and we can give this
|
||||
variable an <span class="emphasis"><em>initial value</em></span> (through an <span class="emphasis"><em>initializer</em></span>.
|
||||
(cf. 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 <span class="bold"><strong>uninitialized</strong></span>. Its actual value exist
|
||||
but has an <span class="emphasis"><em>indeterminate initial value</em></span> (cf. 8.5/11).
|
||||
<code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>
|
||||
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 <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code> and no initial value is given, the
|
||||
variable is <span class="emphasis"><em>formally</em></span> uninitialized. A formally uninitialized
|
||||
optional object has conceptually no value at all and this situation can
|
||||
be tested at runtime. It is formally <span class="emphasis"><em>undefined behavior</em></span>
|
||||
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
|
||||
<span class="emphasis"><em>uninitialized</em></span>.
|
||||
</p>
|
||||
<p>
|
||||
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: <code class="computeroutput"><span class="identifier">EOF</span></code>,
|
||||
<code class="computeroutput"><span class="identifier">npos</span></code>, -1, etc... This is
|
||||
equivalent to adding the special value to the set of possible values of
|
||||
a given type. This super set of <code class="computeroutput"><span class="identifier">T</span></code>
|
||||
plus some <span class="emphasis"><em>nil_t</em></span>—where <code class="computeroutput"><span class="identifier">nil_t</span></code>
|
||||
is some stateless POD—can be modeled in modern languages as a <span class="bold"><strong>discriminated union</strong></span> of T and nil_t. Discriminated
|
||||
unions are often called <span class="emphasis"><em>variants</em></span>. A variant has a
|
||||
<span class="emphasis"><em>current type</em></span>, which in our case is either <code class="computeroutput"><span class="identifier">T</span></code> or <code class="computeroutput"><span class="identifier">nil_t</span></code>.
|
||||
Using the <a href="../../../../../variant/index.html" target="_top">Boost.Variant</a>
|
||||
library, this model can be implemented in terms of <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">variant</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span><span class="identifier">nil_t</span><span class="special">></span></code>. There is precedent for a discriminated
|
||||
union as a model for an optional value: the <a href="http://www.haskell.org/" target="_top">Haskell</a>
|
||||
<span class="bold"><strong>Maybe</strong></span> built-in type constructor. Thus,
|
||||
a discriminated union <code class="computeroutput"><span class="identifier">T</span><span class="special">+</span><span class="identifier">nil_t</span></code>
|
||||
serves as a conceptual foundation.
|
||||
</p>
|
||||
<p>
|
||||
A <code class="computeroutput"><span class="identifier">variant</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span><span class="identifier">nil_t</span><span class="special">></span></code> follows naturally from the traditional
|
||||
idiom of extending the range of possible values adding an additional sentinel
|
||||
value with the special meaning of <span class="emphasis"><em>Nothing</em></span>. However,
|
||||
this additional <span class="emphasis"><em>Nothing</em></span> 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.
|
||||
</p>
|
||||
<p>
|
||||
The observation made in the last paragraph about the irrelevant nature
|
||||
of the additional <code class="computeroutput"><span class="identifier">nil_t</span></code>
|
||||
with respect to <span class="underline">purpose</span> of <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>
|
||||
suggests an alternative model: a <span class="emphasis"><em>container</em></span> that either
|
||||
has a value of <code class="computeroutput"><span class="identifier">T</span></code> or nothing.
|
||||
</p>
|
||||
<p>
|
||||
As of this writing I don't know of any precedent 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.
|
||||
</p>
|
||||
<p>
|
||||
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
|
||||
<span class="emphasis"><em>exact</em></span> semantics required for a wrapper of optional
|
||||
values:
|
||||
</p>
|
||||
<p>
|
||||
Discriminated-union:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>deep-copy</strong></span> semantics: copies of the
|
||||
variant implies copies of the value.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>deep-relational</strong></span> semantics: comparisons
|
||||
between variants matches both current types and values
|
||||
</li>
|
||||
<li class="listitem">
|
||||
If the variant's current type is <code class="computeroutput"><span class="identifier">T</span></code>,
|
||||
it is modeling an <span class="emphasis"><em>initialized</em></span> optional.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
If the variant's current type is not <code class="computeroutput"><span class="identifier">T</span></code>,
|
||||
it is modeling an <span class="emphasis"><em>uninitialized</em></span> optional.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
Testing if the variant's current type is <code class="computeroutput"><span class="identifier">T</span></code>
|
||||
models testing if the optional is initialized
|
||||
</li>
|
||||
<li class="listitem">
|
||||
Trying to extract a <code class="computeroutput"><span class="identifier">T</span></code>
|
||||
from a variant when its current type is not <code class="computeroutput"><span class="identifier">T</span></code>,
|
||||
models the undefined behavior of trying to access the value of an uninitialized
|
||||
optional
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
Single-element container:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>deep-copy</strong></span> semantics: copies of the
|
||||
container implies copies of the value.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>deep-relational</strong></span> semantics: comparisons
|
||||
between containers compare container size and if match, contained value
|
||||
</li>
|
||||
<li class="listitem">
|
||||
If the container is not empty (contains an object of type <code class="computeroutput"><span class="identifier">T</span></code>), it is modeling an <span class="emphasis"><em>initialized</em></span>
|
||||
optional.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
If the container is empty, it is modeling an <span class="emphasis"><em>uninitialized</em></span>
|
||||
optional.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
Testing if the container is empty models testing if the optional is
|
||||
initialized
|
||||
</li>
|
||||
<li class="listitem">
|
||||
Trying to extract a <code class="computeroutput"><span class="identifier">T</span></code>
|
||||
from an empty container models the undefined behavior of trying to
|
||||
access the value of an uninitialized optional
|
||||
</li>
|
||||
</ul></div>
|
||||
</div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014 Andrzej Krzemieński<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
</div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="../../optional/tutorial.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../../optional/tutorial.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="design_overview/the_semantics.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,186 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>The Interface</title>
|
||||
<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||
<link rel="home" href="../../../index.html" title="Boost.Optional">
|
||||
<link rel="up" href="../design_overview.html" title="Design Overview">
|
||||
<link rel="prev" href="the_semantics.html" title="The semantics">
|
||||
<link rel="next" href="../optional_references.html" title="Optional references">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="the_semantics.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../design_overview.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../optional_references.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h4 class="title">
|
||||
<a name="boost_optional.tutorial.design_overview.the_interface"></a><a class="link" href="the_interface.html" title="The Interface">The
|
||||
Interface</a>
|
||||
</h4></div></div></div>
|
||||
<p>
|
||||
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 <code class="computeroutput"><span class="identifier">T</span></code> type
|
||||
as much as possible. In order to choose the proper degree of adoption of
|
||||
the native <code class="computeroutput"><span class="identifier">T</span></code> interface,
|
||||
the following must be noted: Even if all the operations supported by an
|
||||
instance of type <code class="computeroutput"><span class="identifier">T</span></code> are
|
||||
defined for the entire range of values for such a type, an <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>
|
||||
extends such a set of values with a new value for which most (otherwise
|
||||
valid) operations are not defined in terms of <code class="computeroutput"><span class="identifier">T</span></code>.
|
||||
</p>
|
||||
<p>
|
||||
Furthermore, since <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code> itself is merely a <code class="computeroutput"><span class="identifier">T</span></code>
|
||||
wrapper (modeling a <code class="computeroutput"><span class="identifier">T</span></code> supertype),
|
||||
any attempt to define such operations upon uninitialized optionals will
|
||||
be totally artificial w.r.t. <code class="computeroutput"><span class="identifier">T</span></code>.
|
||||
</p>
|
||||
<p>
|
||||
This library chooses an interface which follows from <code class="computeroutput"><span class="identifier">T</span></code>'s
|
||||
interface only for those operations which are well defined (w.r.t the type
|
||||
<code class="computeroutput"><span class="identifier">T</span></code>) even if any of the operands
|
||||
are uninitialized. These operations include: construction, copy-construction,
|
||||
assignment, swap and relational operations.
|
||||
</p>
|
||||
<p>
|
||||
For the value access operations, which are undefined (w.r.t the type <code class="computeroutput"><span class="identifier">T</span></code>) when the operand is uninitialized,
|
||||
a different interface is chosen (which will be explained next).
|
||||
</p>
|
||||
<p>
|
||||
Also, the presence of the possibly uninitialized state requires additional
|
||||
operations not provided by <code class="computeroutput"><span class="identifier">T</span></code>
|
||||
itself which are supported by a special interface.
|
||||
</p>
|
||||
<h6>
|
||||
<a name="boost_optional.tutorial.design_overview.the_interface.h0"></a>
|
||||
<span class="phrase"><a name="boost_optional.tutorial.design_overview.the_interface.lexically_hinted_value_access_in_the_presence_of_possibly_untitialized_optional_objects__the_operators___and___gt_"></a></span><a class="link" href="the_interface.html#boost_optional.tutorial.design_overview.the_interface.lexically_hinted_value_access_in_the_presence_of_possibly_untitialized_optional_objects__the_operators___and___gt_">Lexically-hinted
|
||||
Value Access in the presence of possibly untitialized optional objects:
|
||||
The operators * and -></a>
|
||||
</h6>
|
||||
<p>
|
||||
A relevant feature of a pointer is that it can have a <span class="bold"><strong>null
|
||||
pointer value</strong></span>. This is a <span class="emphasis"><em>special</em></span> 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 nonexistent
|
||||
objects.
|
||||
</p>
|
||||
<p>
|
||||
This meaning of the null pointer value allowed pointers to became a <span class="emphasis"><em>de
|
||||
facto</em></span> 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 <span class="emphasis"><em>refer</em></span>
|
||||
to optional (that is, possibly nonexistent) objects; particularly as optional
|
||||
arguments to a function, but also quite often as optional data members.
|
||||
</p>
|
||||
<p>
|
||||
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: <code class="computeroutput"><span class="special">(</span>
|
||||
<span class="special">*</span><span class="identifier">p</span>
|
||||
<span class="special">=</span> <span class="number">2</span> <span class="special">)</span></code> and <code class="computeroutput"><span class="special">(</span>
|
||||
<span class="identifier">p</span><span class="special">-></span><span class="identifier">foo</span><span class="special">()</span> <span class="special">)</span></code>, implicitly convey the notion of optionality,
|
||||
and this information is tied to the <span class="emphasis"><em>syntax</em></span> of the
|
||||
expressions. That is, the presence of operators <code class="computeroutput"><span class="special">*</span></code>
|
||||
and <code class="computeroutput"><span class="special">-></span></code> tell by themselves
|
||||
—without any additional context— that the expression will be undefined
|
||||
unless the implied pointee actually exist.
|
||||
</p>
|
||||
<p>
|
||||
Such a <span class="emphasis"><em>de facto</em></span> idiom for referring to optional objects
|
||||
can be formalized in the form of a concept: the <a href="../../../../../../utility/OptionalPointee.html" target="_top">OptionalPointee</a>
|
||||
concept. This concept captures the syntactic usage of operators <code class="computeroutput"><span class="special">*</span></code>, <code class="computeroutput"><span class="special">-></span></code>
|
||||
and contextual conversion to <code class="computeroutput"><span class="keyword">bool</span></code>
|
||||
to convey the notion of optionality.
|
||||
</p>
|
||||
<p>
|
||||
However, pointers are good to <span class="underline">refer</span>
|
||||
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.
|
||||
</p>
|
||||
<p>
|
||||
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 <code class="computeroutput"><span class="identifier">X</span></code>, it can use <code class="computeroutput"><span class="identifier">shared_ptr</span><span class="special"><</span><span class="identifier">X</span><span class="special">></span></code>
|
||||
as the return value. However, this requires dynamic allocation of <code class="computeroutput"><span class="identifier">X</span></code>. If <code class="computeroutput"><span class="identifier">X</span></code>
|
||||
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
|
||||
<a href="../../../../../../utility/OptionalPointee.html" target="_top">OptionalPointee</a>
|
||||
concept incarnated by pointers.
|
||||
</p>
|
||||
<h6>
|
||||
<a name="boost_optional.tutorial.design_overview.the_interface.h1"></a>
|
||||
<span class="phrase"><a name="boost_optional.tutorial.design_overview.the_interface.optional_lt_t_gt__as_a_model_of_optionalpointee"></a></span><a class="link" href="the_interface.html#boost_optional.tutorial.design_overview.the_interface.optional_lt_t_gt__as_a_model_of_optionalpointee">Optional<T>
|
||||
as a model of OptionalPointee</a>
|
||||
</h6>
|
||||
<p>
|
||||
For value access operations <code class="computeroutput"><span class="identifier">optional</span><span class="special"><></span></code> uses operators <code class="computeroutput"><span class="special">*</span></code>
|
||||
and <code class="computeroutput"><span class="special">-></span></code> to lexically warn
|
||||
about the possibly uninitialized state appealing to the familiar pointer
|
||||
semantics w.r.t. to null pointers.
|
||||
</p>
|
||||
<div class="warning"><table border="0" summary="Warning">
|
||||
<tr>
|
||||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Warning]" src="../../../../../../../doc/src/images/warning.png"></td>
|
||||
<th align="left">Warning</th>
|
||||
</tr>
|
||||
<tr><td align="left" valign="top"><p>
|
||||
However, it is particularly important to note that <code class="computeroutput"><span class="identifier">optional</span><span class="special"><></span></code> objects are not pointers. <span class="underline"><code class="computeroutput"><span class="identifier">optional</span><span class="special"><></span></code> is not, and does not model, a
|
||||
pointer</span>.
|
||||
</p></td></tr>
|
||||
</table></div>
|
||||
<p>
|
||||
For instance, <code class="computeroutput"><span class="identifier">optional</span><span class="special"><></span></code> does not have shallow-copy so does
|
||||
not alias: two different optionals never refer to the <span class="emphasis"><em>same</em></span>
|
||||
value unless <code class="computeroutput"><span class="identifier">T</span></code> itself is
|
||||
a reference (but may have <span class="emphasis"><em>equivalent</em></span> values). The
|
||||
difference between an <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code> and a pointer must be kept in mind,
|
||||
particularly because the semantics of relational operators are different:
|
||||
since <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>
|
||||
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 <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>
|
||||
by <code class="computeroutput"><span class="identifier">T</span><span class="special">*</span></code>
|
||||
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 <a href="../../../../../../utility/OptionalPointee.html#equal" target="_top"><code class="computeroutput"><span class="identifier">equal_pointees</span><span class="special">()</span></code></a>
|
||||
and <a href="../../../../../../utility/OptionalPointee.html#less" target="_top"><code class="computeroutput"><span class="identifier">less_pointees</span><span class="special">()</span></code></a>
|
||||
instead.
|
||||
</p>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014 Andrzej Krzemieński<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
</div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="the_semantics.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../design_overview.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../optional_references.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,121 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>The semantics</title>
|
||||
<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||
<link rel="home" href="../../../index.html" title="Boost.Optional">
|
||||
<link rel="up" href="../design_overview.html" title="Design Overview">
|
||||
<link rel="prev" href="../design_overview.html" title="Design Overview">
|
||||
<link rel="next" href="the_interface.html" title="The Interface">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="../design_overview.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../design_overview.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="the_interface.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h4 class="title">
|
||||
<a name="boost_optional.tutorial.design_overview.the_semantics"></a><a class="link" href="the_semantics.html" title="The semantics">The
|
||||
semantics</a>
|
||||
</h4></div></div></div>
|
||||
<p>
|
||||
Objects of type <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code> are intended to be used in places where
|
||||
objects of type <code class="computeroutput"><span class="identifier">T</span></code> would
|
||||
but which might be uninitialized. Hence, <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>'s purpose is to formalize the additional
|
||||
possibly uninitialized state. From the perspective of this role, <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>
|
||||
can have the same operational semantics of <code class="computeroutput"><span class="identifier">T</span></code>
|
||||
plus the additional semantics corresponding to this special state. As such,
|
||||
<code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>
|
||||
could be thought of as a <span class="emphasis"><em>supertype</em></span> of <code class="computeroutput"><span class="identifier">T</span></code>. 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 <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code> a <span class="emphasis"><em>subtype</em></span> of
|
||||
<code class="computeroutput"><span class="identifier">T</span></code> 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.
|
||||
</p>
|
||||
<p>
|
||||
We can draw from the purpose of <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code> the required basic semantics:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Default Construction:</strong></span> To introduce
|
||||
a formally uninitialized wrapped object.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Direct Value Construction via copy:</strong></span>
|
||||
To introduce a formally initialized wrapped object whose value is obtained
|
||||
as a copy of some object.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Deep Copy Construction:</strong></span> To obtain
|
||||
a new yet equivalent wrapped object.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Direct Value Assignment (upon initialized):</strong></span>
|
||||
To assign a value to the wrapped object.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Direct Value Assignment (upon uninitialized):</strong></span>
|
||||
To initialize the wrapped object with a value obtained as a copy of
|
||||
some object.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Assignment (upon initialized):</strong></span> To
|
||||
assign to the wrapped object the value of another wrapped object.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Assignment (upon uninitialized):</strong></span> To
|
||||
initialize the wrapped object with value of another wrapped object.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Deep Relational Operations (when supported by
|
||||
the type T):</strong></span> To compare wrapped object values taking into
|
||||
account the presence of uninitialized states.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Value access:</strong></span> To unwrap the wrapped
|
||||
object.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Initialization state query:</strong></span> To determine
|
||||
if the object is formally initialized or not.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>Swap:</strong></span> To exchange wrapped objects.
|
||||
(with whatever exception safety guarantees are provided by <code class="computeroutput"><span class="identifier">T</span></code>'s swap).
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="bold"><strong>De-initialization:</strong></span> To release the
|
||||
wrapped object (if any) and leave the wrapper in the uninitialized
|
||||
state.
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014 Andrzej Krzemieński<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
</div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="../design_overview.html"><img src="../../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../design_overview.html"><img src="../../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../../index.html"><img src="../../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="the_interface.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,175 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Exception Safety Guarantees</title>
|
||||
<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||
<link rel="home" href="../../index.html" title="Boost.Optional">
|
||||
<link rel="up" href="../../optional/tutorial.html" title="Tutorial">
|
||||
<link rel="prev" href="a_note_about_optional_bool_.html" title="A note about optional<bool>">
|
||||
<link rel="next" href="type_requirements.html" title="Type requirements">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="a_note_about_optional_bool_.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../../optional/tutorial.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="type_requirements.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_optional.tutorial.exception_safety_guarantees"></a><a class="link" href="exception_safety_guarantees.html" title="Exception Safety Guarantees">Exception
|
||||
Safety Guarantees</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
This library assumes that <code class="computeroutput"><span class="identifier">T</span></code>'s
|
||||
destructor does not throw exceptions. If it does, the behaviour of many operations
|
||||
on <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code> is
|
||||
undefined.
|
||||
</p>
|
||||
<p>
|
||||
The following mutating operations never throw exceptions:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
<code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="keyword">operator</span><span class="special">=</span> <span class="special">(</span> <span class="identifier">none_t</span>
|
||||
<span class="special">)</span> <span class="keyword">noexcept</span></code>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">reset</span><span class="special">()</span> <span class="keyword">noexcept</span></code>
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
In addition, the following constructors and the destructor never throw exceptions:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
<code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">optional</span><span class="special">()</span>
|
||||
<span class="keyword">noexcept</span></code>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">optional</span><span class="special">(</span>
|
||||
<span class="identifier">none_t</span> <span class="special">)</span>
|
||||
<span class="keyword">noexcept</span></code>
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
Regarding the following assignment functions:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
<code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="keyword">operator</span><span class="special">=</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="special">)</span></code>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="keyword">operator</span><span class="special">=</span> <span class="special">(</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="special">)</span></code>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<code class="computeroutput"><span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">></span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="keyword">operator</span><span class="special">=</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">U</span><span class="special">></span> <span class="keyword">const</span><span class="special">&</span> <span class="special">)</span></code>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<code class="computeroutput"><span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">InPlaceFactory</span><span class="special">></span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="keyword">operator</span><span class="special">=</span> <span class="special">(</span> <span class="identifier">InPlaceFactory</span>
|
||||
<span class="keyword">const</span><span class="special">&</span>
|
||||
<span class="special">)</span></code>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<code class="computeroutput"><span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">TypedInPlaceFactory</span><span class="special">></span> <span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="keyword">operator</span><span class="special">=</span> <span class="special">(</span> <span class="identifier">TypedInPlaceFactory</span>
|
||||
<span class="keyword">const</span><span class="special">&</span>
|
||||
<span class="special">)</span> </code>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">>::</span><span class="identifier">reset</span><span class="special">(</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="special">)</span></code>
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
They forward calls to the corresponding <code class="computeroutput"><span class="identifier">T</span></code>'s
|
||||
constructors or assignments (depending on whether the optional object is
|
||||
initialized or not); so if both <code class="computeroutput"><span class="identifier">T</span></code>'s
|
||||
constructor and the assignment provide strong exception safety guarantee,
|
||||
<code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>'s
|
||||
assignment also provides strong exception safety guarantee; otherwise we
|
||||
only get the basic guarantee. Additionally, if both involved <code class="computeroutput"><span class="identifier">T</span></code>'s constructor and the assignment never
|
||||
throw, <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>'s
|
||||
assignment also never throws.
|
||||
</p>
|
||||
<p>
|
||||
Unless <code class="computeroutput"><span class="identifier">T</span></code>'s constructor or
|
||||
assignment throws, assignments to <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>
|
||||
do not throw anything else on its own. A throw during assignment never changes
|
||||
the initialization state of any optional object involved:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="identifier">opt1</span><span class="special">(</span><span class="identifier">val1</span><span class="special">);</span>
|
||||
<span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span> <span class="identifier">opt2</span><span class="special">(</span><span class="identifier">val2</span><span class="special">);</span>
|
||||
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">opt1</span><span class="special">);</span>
|
||||
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">opt2</span><span class="special">);</span>
|
||||
|
||||
<span class="keyword">try</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">opt1</span> <span class="special">=</span> <span class="identifier">opt2</span><span class="special">;</span> <span class="comment">// throws</span>
|
||||
<span class="special">}</span>
|
||||
<span class="keyword">catch</span><span class="special">(...)</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">opt1</span><span class="special">);</span>
|
||||
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">opt2</span><span class="special">);</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
This also applies to move assignments/constructors. However, move operations
|
||||
are made no-throw more often.
|
||||
</p>
|
||||
<p>
|
||||
Operation <code class="computeroutput"><span class="identifier">emplace</span></code> provides
|
||||
basic exception safety guarantee. If it throws, the optional object becomes
|
||||
uninitialized regardless of its initial state, and its previous contained
|
||||
value (if any) is destroyed. It doesn't call any assignment or move/copy
|
||||
constructor on <code class="computeroutput"><span class="identifier">T</span></code>.
|
||||
</p>
|
||||
<h5>
|
||||
<a name="boost_optional.tutorial.exception_safety_guarantees.h0"></a>
|
||||
<span class="phrase"><a name="boost_optional.tutorial.exception_safety_guarantees.swap"></a></span><a class="link" href="exception_safety_guarantees.html#boost_optional.tutorial.exception_safety_guarantees.swap">Swap</a>
|
||||
</h5>
|
||||
<p>
|
||||
Unless <code class="computeroutput"><span class="identifier">swap</span></code> on optional is
|
||||
customized, its primary implementation forwards calls to <code class="computeroutput"><span class="identifier">T</span></code>'s
|
||||
<code class="computeroutput"><span class="identifier">swap</span></code> or move constructor
|
||||
(depending on the initialization state of the optional objects). Thus, if
|
||||
both <code class="computeroutput"><span class="identifier">T</span></code>'s <code class="computeroutput"><span class="identifier">swap</span></code>
|
||||
and move constructor never throw, <code class="computeroutput"><span class="identifier">swap</span></code>
|
||||
on <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code> never
|
||||
throws. similarly, if both <code class="computeroutput"><span class="identifier">T</span></code>'s
|
||||
<code class="computeroutput"><span class="identifier">swap</span></code> and move constructor
|
||||
offer strong guarantee, <code class="computeroutput"><span class="identifier">swap</span></code>
|
||||
on <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code> also
|
||||
offers a strong guarantee.
|
||||
</p>
|
||||
<p>
|
||||
In case <code class="computeroutput"><span class="identifier">swap</span></code> on optional
|
||||
is customized, the call to <code class="computeroutput"><span class="identifier">T</span></code>'s
|
||||
move constructor are replaced with the calls to <code class="computeroutput"><span class="identifier">T</span></code>'s
|
||||
default constructor followed by <code class="computeroutput"><span class="identifier">swap</span></code>.
|
||||
(This is more useful on older compilers that do not support move semantics,
|
||||
when one wants to acheive stronger exception safety guarantees.) In this
|
||||
case the exception safety guarantees for <code class="computeroutput"><span class="identifier">swap</span></code>
|
||||
are reliant on the guarantees of <code class="computeroutput"><span class="identifier">T</span></code>'s
|
||||
<code class="computeroutput"><span class="identifier">swap</span></code> and default constructor
|
||||
</p>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014 Andrzej Krzemieński<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
</div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="a_note_about_optional_bool_.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../../optional/tutorial.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="type_requirements.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
197
doc/html/boost_optional/tutorial/in_place_factories.html
Normal file
197
doc/html/boost_optional/tutorial/in_place_factories.html
Normal file
@ -0,0 +1,197 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>In-Place Factories</title>
|
||||
<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||
<link rel="home" href="../../index.html" title="Boost.Optional">
|
||||
<link rel="up" href="../../optional/tutorial.html" title="Tutorial">
|
||||
<link rel="prev" href="rebinding_semantics_for_assignment_of_optional_references.html" title="Rebinding semantics for assignment of optional references">
|
||||
<link rel="next" href="a_note_about_optional_bool_.html" title="A note about optional<bool>">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="rebinding_semantics_for_assignment_of_optional_references.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../../optional/tutorial.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="a_note_about_optional_bool_.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_optional.tutorial.in_place_factories"></a><a class="link" href="in_place_factories.html" title="In-Place Factories">In-Place
|
||||
Factories</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
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 <a href="../../../../../utility/CopyConstructible.html" target="_top">Copy Constructible</a>,
|
||||
but also requires the existence of a fully constructed object, often temporary,
|
||||
just to follow the copy from:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">X</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">X</span> <span class="special">(</span> <span class="keyword">int</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="special">)</span> <span class="special">;</span>
|
||||
<span class="special">}</span> <span class="special">;</span>
|
||||
|
||||
<span class="keyword">class</span> <span class="identifier">W</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">X</span> <span class="identifier">wrapped_</span> <span class="special">;</span>
|
||||
|
||||
<span class="keyword">public</span><span class="special">:</span>
|
||||
|
||||
<span class="identifier">W</span> <span class="special">(</span> <span class="identifier">X</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">x</span> <span class="special">)</span> <span class="special">:</span> <span class="identifier">wrapped_</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span> <span class="special">{}</span>
|
||||
<span class="special">}</span> <span class="special">;</span>
|
||||
|
||||
<span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span>
|
||||
<span class="special">{</span>
|
||||
<span class="comment">// Temporary object created.</span>
|
||||
<span class="identifier">W</span> <span class="special">(</span> <span class="identifier">X</span><span class="special">(</span><span class="number">123</span><span class="special">,</span><span class="string">"hello"</span><span class="special">)</span> <span class="special">)</span> <span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
A solution to this problem is to support direct construction of the contained
|
||||
object right in the container's storage. In this scheme, the user only needs
|
||||
to supply the arguments to the constructor to use in the wrapped object construction.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">W</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">X</span> <span class="identifier">wrapped_</span> <span class="special">;</span>
|
||||
|
||||
<span class="keyword">public</span><span class="special">:</span>
|
||||
|
||||
<span class="identifier">W</span> <span class="special">(</span> <span class="identifier">X</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">x</span> <span class="special">)</span> <span class="special">:</span> <span class="identifier">wrapped_</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span> <span class="special">{}</span>
|
||||
<span class="identifier">W</span> <span class="special">(</span> <span class="keyword">int</span> <span class="identifier">a0</span><span class="special">,</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">a1</span><span class="special">)</span> <span class="special">:</span> <span class="identifier">wrapped_</span><span class="special">(</span><span class="identifier">a0</span><span class="special">,</span><span class="identifier">a1</span><span class="special">)</span> <span class="special">{}</span>
|
||||
<span class="special">}</span> <span class="special">;</span>
|
||||
|
||||
<span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span>
|
||||
<span class="special">{</span>
|
||||
<span class="comment">// Wrapped object constructed in-place</span>
|
||||
<span class="comment">// No temporary created.</span>
|
||||
<span class="identifier">W</span> <span class="special">(</span><span class="number">123</span><span class="special">,</span><span class="string">"hello"</span><span class="special">)</span> <span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
<p>
|
||||
The solution presented in this library is the family of <span class="bold"><strong>InPlaceFactories</strong></span>
|
||||
and <span class="bold"><strong>TypedInPlaceFactories</strong></span>. 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.
|
||||
</p>
|
||||
<p>
|
||||
For example, one member of this family looks like:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span><span class="keyword">class</span> <span class="identifier">A0</span><span class="special">,</span> <span class="keyword">class</span> <span class="identifier">A1</span><span class="special">></span>
|
||||
<span class="keyword">class</span> <span class="identifier">TypedInPlaceFactory2</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">A0</span> <span class="identifier">m_a0</span> <span class="special">;</span> <span class="identifier">A1</span> <span class="identifier">m_a1</span> <span class="special">;</span>
|
||||
|
||||
<span class="keyword">public</span><span class="special">:</span>
|
||||
|
||||
<span class="identifier">TypedInPlaceFactory2</span><span class="special">(</span> <span class="identifier">A0</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">a0</span><span class="special">,</span> <span class="identifier">A1</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">a1</span> <span class="special">)</span> <span class="special">:</span> <span class="identifier">m_a0</span><span class="special">(</span><span class="identifier">a0</span><span class="special">),</span> <span class="identifier">m_a1</span><span class="special">(</span><span class="identifier">a1</span><span class="special">)</span> <span class="special">{}</span>
|
||||
|
||||
<span class="keyword">void</span> <span class="identifier">construct</span> <span class="special">(</span> <span class="keyword">void</span><span class="special">*</span> <span class="identifier">p</span> <span class="special">)</span> <span class="special">{</span> <span class="keyword">new</span> <span class="special">(</span><span class="identifier">p</span><span class="special">)</span> <span class="identifier">T</span><span class="special">(</span><span class="identifier">m_a0</span><span class="special">,</span><span class="identifier">m_a1</span><span class="special">)</span> <span class="special">;</span> <span class="special">}</span>
|
||||
<span class="special">}</span> <span class="special">;</span>
|
||||
</pre>
|
||||
<p>
|
||||
A wrapper class aware of this can use it as:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">W</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">X</span> <span class="identifier">wrapped_</span> <span class="special">;</span>
|
||||
|
||||
<span class="keyword">public</span><span class="special">:</span>
|
||||
|
||||
<span class="identifier">W</span> <span class="special">(</span> <span class="identifier">X</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">x</span> <span class="special">)</span> <span class="special">:</span> <span class="identifier">wrapped_</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span> <span class="special">{}</span>
|
||||
<span class="identifier">W</span> <span class="special">(</span> <span class="identifier">TypedInPlaceFactory2</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">fac</span> <span class="special">)</span> <span class="special">{</span> <span class="identifier">fac</span><span class="special">.</span><span class="identifier">construct</span><span class="special">(&</span><span class="identifier">wrapped_</span><span class="special">)</span> <span class="special">;</span> <span class="special">}</span>
|
||||
<span class="special">}</span> <span class="special">;</span>
|
||||
|
||||
<span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span>
|
||||
<span class="special">{</span>
|
||||
<span class="comment">// Wrapped object constructed in-place via a TypedInPlaceFactory.</span>
|
||||
<span class="comment">// No temporary created.</span>
|
||||
<span class="identifier">W</span> <span class="special">(</span> <span class="identifier">TypedInPlaceFactory2</span><span class="special"><</span><span class="identifier">X</span><span class="special">,</span><span class="keyword">int</span><span class="special">,</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">>(</span><span class="number">123</span><span class="special">,</span><span class="string">"hello"</span><span class="special">))</span> <span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
The factories are divided in two groups:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
<span class="underline">TypedInPlaceFactories</span>: those which
|
||||
take the target type as a primary template parameter.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
<span class="underline">InPlaceFactories</span>: those with a
|
||||
template <code class="computeroutput"><span class="identifier">construct</span><span class="special">(</span><span class="keyword">void</span><span class="special">*)</span></code>
|
||||
member function taking the target type.
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
Within each group, all the family members differ only in the number of parameters
|
||||
allowed.
|
||||
</p>
|
||||
<p>
|
||||
This library provides an overloaded set of helper template functions to construct
|
||||
these factories without requiring unnecessary template parameters:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">A0</span><span class="special">,...,</span><span class="keyword">class</span> <span class="identifier">AN</span><span class="special">></span>
|
||||
<span class="identifier">InPlaceFactoryN</span> <span class="special"><</span><span class="identifier">A0</span><span class="special">,...,</span><span class="identifier">AN</span><span class="special">></span> <span class="identifier">in_place</span> <span class="special">(</span> <span class="identifier">A0</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">a0</span><span class="special">,</span> <span class="special">...,</span> <span class="identifier">AN</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">aN</span><span class="special">)</span> <span class="special">;</span>
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span><span class="keyword">class</span> <span class="identifier">A0</span><span class="special">,...,</span><span class="keyword">class</span> <span class="identifier">AN</span><span class="special">></span>
|
||||
<span class="identifier">TypedInPlaceFactoryN</span> <span class="special"><</span><span class="identifier">T</span><span class="special">,</span><span class="identifier">A0</span><span class="special">,...,</span><span class="identifier">AN</span><span class="special">></span> <span class="identifier">in_place</span> <span class="special">(</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">a0</span><span class="special">,</span> <span class="identifier">A0</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">a0</span><span class="special">,</span> <span class="special">...,</span> <span class="identifier">AN</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">aN</span><span class="special">)</span> <span class="special">;</span>
|
||||
</pre>
|
||||
<p>
|
||||
In-place factories can be used generically by the wrapper and user as follows:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">W</span>
|
||||
<span class="special">{</span>
|
||||
<span class="identifier">X</span> <span class="identifier">wrapped_</span> <span class="special">;</span>
|
||||
|
||||
<span class="keyword">public</span><span class="special">:</span>
|
||||
|
||||
<span class="identifier">W</span> <span class="special">(</span> <span class="identifier">X</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">x</span> <span class="special">)</span> <span class="special">:</span> <span class="identifier">wrapped_</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span> <span class="special">{}</span>
|
||||
|
||||
<span class="keyword">template</span><span class="special"><</span> <span class="keyword">class</span> <span class="identifier">InPlaceFactory</span> <span class="special">></span>
|
||||
<span class="identifier">W</span> <span class="special">(</span> <span class="identifier">InPlaceFactory</span> <span class="keyword">const</span><span class="special">&</span> <span class="identifier">fac</span> <span class="special">)</span> <span class="special">{</span> <span class="identifier">fac</span><span class="special">.</span><span class="keyword">template</span> <span class="special"><</span><span class="identifier">X</span><span class="special">></span><span class="identifier">construct</span><span class="special">(&</span><span class="identifier">wrapped_</span><span class="special">)</span> <span class="special">;</span> <span class="special">}</span>
|
||||
|
||||
<span class="special">}</span> <span class="special">;</span>
|
||||
|
||||
<span class="keyword">void</span> <span class="identifier">foo</span><span class="special">()</span>
|
||||
<span class="special">{</span>
|
||||
<span class="comment">// Wrapped object constructed in-place via a InPlaceFactory.</span>
|
||||
<span class="comment">// No temporary created.</span>
|
||||
<span class="identifier">W</span> <span class="special">(</span> <span class="identifier">in_place</span><span class="special">(</span><span class="number">123</span><span class="special">,</span><span class="string">"hello"</span><span class="special">)</span> <span class="special">)</span> <span class="special">;</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
<p>
|
||||
The factories are implemented in the headers: <a href="../../../../../../boost/utility/in_place_factory.hpp" target="_top">in_place_factory.hpp</a>
|
||||
and <a href="../../../../../../boost/utility/typed_in_place_factory.hpp" target="_top">typed_in_place_factory.hpp</a>
|
||||
</p>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014 Andrzej Krzemieński<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
</div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="rebinding_semantics_for_assignment_of_optional_references.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../../optional/tutorial.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="a_note_about_optional_bool_.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
129
doc/html/boost_optional/tutorial/motivation.html
Normal file
129
doc/html/boost_optional/tutorial/motivation.html
Normal file
@ -0,0 +1,129 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Motivation</title>
|
||||
<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||
<link rel="home" href="../../index.html" title="Chapter 1. Boost.Optional">
|
||||
<link rel="up" href="../../optional/tutorial.html" title="Tutorial">
|
||||
<link rel="prev" href="../../optional/tutorial.html" title="Tutorial">
|
||||
<link rel="next" href="design_overview.html" title="Design Overview">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="../../optional/tutorial.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../../optional/tutorial.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="design_overview.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_optional.tutorial.motivation"></a><a class="link" href="motivation.html" title="Motivation">Motivation</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
Consider these functions which should return a value but which might not
|
||||
have a value to return:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
(A) <code class="computeroutput"><span class="keyword">double</span> <span class="identifier">sqrt</span><span class="special">(</span><span class="keyword">double</span> <span class="identifier">n</span> <span class="special">);</span></code>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
(B) <code class="computeroutput"><span class="keyword">char</span> <span class="identifier">get_async_input</span><span class="special">();</span></code>
|
||||
</li>
|
||||
<li class="listitem">
|
||||
(C) <code class="computeroutput"><span class="identifier">point</span> <span class="identifier">polygon</span><span class="special">::</span><span class="identifier">get_any_point_effectively_inside</span><span class="special">();</span></code>
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
There are different approaches to the issue of not having a value to return.
|
||||
</p>
|
||||
<p>
|
||||
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 assert 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.
|
||||
</p>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
<p>
|
||||
A similar situation occurs with function (C): it is conceptually an error
|
||||
to ask a <span class="emphasis"><em>null-area</em></span> 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.
|
||||
</p>
|
||||
<p>
|
||||
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 <code class="computeroutput"><span class="identifier">EOF</span></code>, <code class="computeroutput"><span class="identifier">string</span><span class="special">::</span><span class="identifier">npos</span></code>,
|
||||
points at infinity, etc...
|
||||
</p>
|
||||
<p>
|
||||
When those values exist, i.e. the return type can hold all meaningful values
|
||||
<span class="emphasis"><em>plus</em></span> the <span class="emphasis"><em>signal</em></span> 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 <code class="computeroutput"><span class="keyword">int</span></code>
|
||||
in place of <code class="computeroutput"><span class="keyword">char</span></code>; or a compound
|
||||
type, such as <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="identifier">point</span><span class="special">,</span><span class="keyword">bool</span><span class="special">></span></code>.
|
||||
</p>
|
||||
<p>
|
||||
Returning a <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="identifier">T</span><span class="special">,</span><span class="keyword">bool</span><span class="special">></span></code>, 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:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="keyword">char</span><span class="special">,</span><span class="keyword">bool</span><span class="special">></span> <span class="identifier">get_async_input</span><span class="special">();</span>
|
||||
<span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="identifier">point</span><span class="special">,</span><span class="keyword">bool</span><span class="special">></span> <span class="identifier">polygon</span><span class="special">::</span><span class="identifier">get_any_point_effectively_inside</span><span class="special">();</span>
|
||||
</pre>
|
||||
<p>
|
||||
These functions use a consistent interface for dealing with possibly nonexistent
|
||||
results:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">std</span><span class="special">::</span><span class="identifier">pair</span><span class="special"><</span><span class="identifier">point</span><span class="special">,</span><span class="keyword">bool</span><span class="special">></span> <span class="identifier">p</span> <span class="special">=</span> <span class="identifier">poly</span><span class="special">.</span><span class="identifier">get_any_point_effectively_inside</span><span class="special">();</span>
|
||||
<span class="keyword">if</span> <span class="special">(</span> <span class="identifier">p</span><span class="special">.</span><span class="identifier">second</span> <span class="special">)</span>
|
||||
<span class="identifier">flood_fill</span><span class="special">(</span><span class="identifier">p</span><span class="special">.</span><span class="identifier">first</span><span class="special">);</span>
|
||||
</pre>
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
<p>
|
||||
Clearly, we need a better idiom.
|
||||
</p>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014 Andrzej Krzemieński<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
</div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="../../optional/tutorial.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../../optional/tutorial.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="design_overview.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
115
doc/html/boost_optional/tutorial/optional_references.html
Normal file
115
doc/html/boost_optional/tutorial/optional_references.html
Normal file
@ -0,0 +1,115 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Optional references</title>
|
||||
<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||
<link rel="home" href="../../index.html" title="Boost.Optional">
|
||||
<link rel="up" href="../../optional/tutorial.html" title="Tutorial">
|
||||
<link rel="prev" href="design_overview/the_interface.html" title="The Interface">
|
||||
<link rel="next" href="rebinding_semantics_for_assignment_of_optional_references.html" title="Rebinding semantics for assignment of optional references">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="design_overview/the_interface.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../../optional/tutorial.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="rebinding_semantics_for_assignment_of_optional_references.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_optional.tutorial.optional_references"></a><a class="link" href="optional_references.html" title="Optional references">Optional
|
||||
references</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
This library allows the template parameter <code class="computeroutput"><span class="identifier">T</span></code>
|
||||
to be of reference type: <code class="computeroutput"><span class="identifier">T</span><span class="special">&</span></code>, and to some extent, <code class="computeroutput"><span class="identifier">T</span>
|
||||
<span class="keyword">const</span><span class="special">&</span></code>.
|
||||
</p>
|
||||
<p>
|
||||
However, since references are not real objects some restrictions apply and
|
||||
some operations are not available in this case:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
Converting constructors
|
||||
</li>
|
||||
<li class="listitem">
|
||||
Converting assignment
|
||||
</li>
|
||||
<li class="listitem">
|
||||
InPlace construction
|
||||
</li>
|
||||
<li class="listitem">
|
||||
InPlace assignment
|
||||
</li>
|
||||
<li class="listitem">
|
||||
Value-access via pointer
|
||||
</li>
|
||||
</ul></div>
|
||||
<p>
|
||||
Also, even though <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">&></span></code>
|
||||
treats it wrapped pseudo-object much as a real value, a true real reference
|
||||
is stored so aliasing will ocurr:
|
||||
</p>
|
||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||
<li class="listitem">
|
||||
Copies of <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">&></span></code>
|
||||
will copy the references but all these references will nonetheless refer
|
||||
to the same object.
|
||||
</li>
|
||||
<li class="listitem">
|
||||
Value-access will actually provide access to the referenced object rather
|
||||
than the reference itself.
|
||||
</li>
|
||||
</ul></div>
|
||||
<div class="warning"><table border="0" summary="Warning">
|
||||
<tr>
|
||||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Warning]" src="../../../../../../doc/src/images/warning.png"></td>
|
||||
<th align="left">Warning</th>
|
||||
</tr>
|
||||
<tr><td align="left" valign="top"><p>
|
||||
On compilers that do not conform to Standard C++ rules of reference binding,
|
||||
operations on optional references might give adverse results: rather than
|
||||
binding a reference to a designated object they may create an unexpected
|
||||
temporary and bind to it. For more details see <a class="link" href="../dependencies_and_portability/optional_reference_binding.html" title="Optional Reference Binding">Dependencies
|
||||
and Portability section</a>.
|
||||
</p></td></tr>
|
||||
</table></div>
|
||||
<h5>
|
||||
<a name="boost_optional.tutorial.optional_references.h0"></a>
|
||||
<span class="phrase"><a name="boost_optional.tutorial.optional_references.rvalue_references"></a></span><a class="link" href="optional_references.html#boost_optional.tutorial.optional_references.rvalue_references">Rvalue
|
||||
references</a>
|
||||
</h5>
|
||||
<p>
|
||||
Rvalue references and lvalue references to const have the ability in C++
|
||||
to extend the life time of a temporary they bind to. Optional references
|
||||
do not have this capability, therefore to avoid surprising effects it is
|
||||
not possible to initialize an optional references from a temporary. Optional
|
||||
rvalue references are disabled altogether. Also, the initialization and assignment
|
||||
of an optional reference to const from rvalue reference is disabled.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">const</span> <span class="keyword">int</span><span class="special">&</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">1</span><span class="special">;</span> <span class="comment">// legal</span>
|
||||
<span class="identifier">optional</span><span class="special"><</span><span class="keyword">const</span> <span class="keyword">int</span><span class="special">&></span> <span class="identifier">oi</span> <span class="special">=</span> <span class="number">1</span><span class="special">;</span> <span class="comment">// illegal</span>
|
||||
</pre>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014 Andrzej Krzemieński<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
</div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="design_overview/the_interface.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../../optional/tutorial.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="rebinding_semantics_for_assignment_of_optional_references.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,149 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Rebinding semantics for assignment of optional references</title>
|
||||
<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||
<link rel="home" href="../../index.html" title="Boost.Optional">
|
||||
<link rel="up" href="../../optional/tutorial.html" title="Tutorial">
|
||||
<link rel="prev" href="optional_references.html" title="Optional references">
|
||||
<link rel="next" href="in_place_factories.html" title="In-Place Factories">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="optional_references.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../../optional/tutorial.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="in_place_factories.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_optional.tutorial.rebinding_semantics_for_assignment_of_optional_references"></a><a class="link" href="rebinding_semantics_for_assignment_of_optional_references.html" title="Rebinding semantics for assignment of optional references">Rebinding
|
||||
semantics for assignment of optional references</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
If you assign to an <span class="emphasis"><em>uninitialized </em></span> <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">&></span></code>
|
||||
the effect is to bind (for the first time) to the object. Clearly, there
|
||||
is no other choice.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">x</span> <span class="special">=</span> <span class="number">1</span> <span class="special">;</span>
|
||||
<span class="keyword">int</span><span class="special">&</span> <span class="identifier">rx</span> <span class="special">=</span> <span class="identifier">x</span> <span class="special">;</span>
|
||||
<span class="identifier">optional</span><span class="special"><</span><span class="keyword">int</span><span class="special">&></span> <span class="identifier">ora</span> <span class="special">;</span>
|
||||
<span class="identifier">optional</span><span class="special"><</span><span class="keyword">int</span><span class="special">&></span> <span class="identifier">orb</span><span class="special">(</span><span class="identifier">x</span><span class="special">)</span> <span class="special">;</span>
|
||||
<span class="identifier">ora</span> <span class="special">=</span> <span class="identifier">orb</span> <span class="special">;</span> <span class="comment">// now 'ora' is bound to 'x' through 'rx'</span>
|
||||
<span class="special">*</span><span class="identifier">ora</span> <span class="special">=</span> <span class="number">2</span> <span class="special">;</span> <span class="comment">// Changes value of 'x' through 'ora'</span>
|
||||
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">x</span><span class="special">==</span><span class="number">2</span><span class="special">);</span>
|
||||
</pre>
|
||||
<p>
|
||||
If you assign to a bare C++ reference, the assignment is forwarded to the
|
||||
referenced object; its value changes but the reference is never rebound.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">a</span> <span class="special">=</span> <span class="number">1</span> <span class="special">;</span>
|
||||
<span class="keyword">int</span><span class="special">&</span> <span class="identifier">ra</span> <span class="special">=</span> <span class="identifier">a</span> <span class="special">;</span>
|
||||
<span class="keyword">int</span> <span class="identifier">b</span> <span class="special">=</span> <span class="number">2</span> <span class="special">;</span>
|
||||
<span class="keyword">int</span><span class="special">&</span> <span class="identifier">rb</span> <span class="special">=</span> <span class="identifier">b</span> <span class="special">;</span>
|
||||
<span class="identifier">ra</span> <span class="special">=</span> <span class="identifier">rb</span> <span class="special">;</span> <span class="comment">// Changes the value of 'a' to 'b'</span>
|
||||
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">a</span><span class="special">==</span><span class="identifier">b</span><span class="special">);</span>
|
||||
<span class="identifier">b</span> <span class="special">=</span> <span class="number">3</span> <span class="special">;</span>
|
||||
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">ra</span><span class="special">!=</span><span class="identifier">b</span><span class="special">);</span> <span class="comment">// 'ra' is not rebound to 'b'</span>
|
||||
</pre>
|
||||
<p>
|
||||
Now, if you assign to an <span class="emphasis"><em>initialized </em></span> <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">&></span></code>,
|
||||
the effect is to <span class="bold"><strong>rebind</strong></span> to the new object
|
||||
instead of assigning the referee. This is unlike bare C++ references.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">a</span> <span class="special">=</span> <span class="number">1</span> <span class="special">;</span>
|
||||
<span class="keyword">int</span> <span class="identifier">b</span> <span class="special">=</span> <span class="number">2</span> <span class="special">;</span>
|
||||
<span class="keyword">int</span><span class="special">&</span> <span class="identifier">ra</span> <span class="special">=</span> <span class="identifier">a</span> <span class="special">;</span>
|
||||
<span class="keyword">int</span><span class="special">&</span> <span class="identifier">rb</span> <span class="special">=</span> <span class="identifier">b</span> <span class="special">;</span>
|
||||
<span class="identifier">optional</span><span class="special"><</span><span class="keyword">int</span><span class="special">&></span> <span class="identifier">ora</span><span class="special">(</span><span class="identifier">ra</span><span class="special">)</span> <span class="special">;</span>
|
||||
<span class="identifier">optional</span><span class="special"><</span><span class="keyword">int</span><span class="special">&></span> <span class="identifier">orb</span><span class="special">(</span><span class="identifier">rb</span><span class="special">)</span> <span class="special">;</span>
|
||||
<span class="identifier">ora</span> <span class="special">=</span> <span class="identifier">orb</span> <span class="special">;</span> <span class="comment">// 'ora' is rebound to 'b'</span>
|
||||
<span class="special">*</span><span class="identifier">ora</span> <span class="special">=</span> <span class="number">3</span> <span class="special">;</span> <span class="comment">// Changes value of 'b' (not 'a')</span>
|
||||
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">a</span><span class="special">==</span><span class="number">1</span><span class="special">);</span>
|
||||
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">b</span><span class="special">==</span><span class="number">3</span><span class="special">);</span>
|
||||
</pre>
|
||||
<h5>
|
||||
<a name="boost_optional.tutorial.rebinding_semantics_for_assignment_of_optional_references.h0"></a>
|
||||
<span class="phrase"><a name="boost_optional.tutorial.rebinding_semantics_for_assignment_of_optional_references.rationale"></a></span><a class="link" href="rebinding_semantics_for_assignment_of_optional_references.html#boost_optional.tutorial.rebinding_semantics_for_assignment_of_optional_references.rationale">Rationale</a>
|
||||
</h5>
|
||||
<p>
|
||||
Rebinding semantics for the assignment of <span class="emphasis"><em>initialized </em></span>
|
||||
<code class="computeroutput"><span class="identifier">optional</span></code> references has been
|
||||
chosen to provide <span class="bold"><strong>consistency among initialization
|
||||
states</strong></span> even at the expense of lack of consistency with the semantics
|
||||
of bare C++ references. It is true that <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">U</span><span class="special">></span></code>
|
||||
strives to behave as much as possible as <code class="computeroutput"><span class="identifier">U</span></code>
|
||||
does whenever it is initialized; but in the case when <code class="computeroutput"><span class="identifier">U</span></code>
|
||||
is <code class="computeroutput"><span class="identifier">T</span><span class="special">&</span></code>,
|
||||
doing so would result in inconsistent behavior w.r.t to the lvalue initialization
|
||||
state.
|
||||
</p>
|
||||
<p>
|
||||
Imagine <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">&></span></code>
|
||||
forwarding assignment to the referenced object (thus changing the referenced
|
||||
object value but not rebinding), and consider the following code:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">optional</span><span class="special"><</span><span class="keyword">int</span><span class="special">&></span> <span class="identifier">a</span> <span class="special">=</span> <span class="identifier">get</span><span class="special">();</span>
|
||||
<span class="keyword">int</span> <span class="identifier">x</span> <span class="special">=</span> <span class="number">1</span> <span class="special">;</span>
|
||||
<span class="keyword">int</span><span class="special">&</span> <span class="identifier">rx</span> <span class="special">=</span> <span class="identifier">x</span> <span class="special">;</span>
|
||||
<span class="identifier">optional</span><span class="special"><</span><span class="keyword">int</span><span class="special">&></span> <span class="identifier">b</span><span class="special">(</span><span class="identifier">rx</span><span class="special">);</span>
|
||||
<span class="identifier">a</span> <span class="special">=</span> <span class="identifier">b</span> <span class="special">;</span>
|
||||
</pre>
|
||||
<p>
|
||||
What does the assignment do?
|
||||
</p>
|
||||
<p>
|
||||
If <code class="computeroutput"><span class="identifier">a</span></code> is <span class="emphasis"><em>uninitialized</em></span>,
|
||||
the answer is clear: it binds to <code class="computeroutput"><span class="identifier">x</span></code>
|
||||
(we now have another reference to <code class="computeroutput"><span class="identifier">x</span></code>).
|
||||
But what if <code class="computeroutput"><span class="identifier">a</span></code> is already
|
||||
<span class="emphasis"><em>initialized</em></span>? it would change the value of the referenced
|
||||
object (whatever that is); which is inconsistent with the other possible
|
||||
case.
|
||||
</p>
|
||||
<p>
|
||||
If <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">&></span></code>
|
||||
would assign just like <code class="computeroutput"><span class="identifier">T</span><span class="special">&</span></code> does, you would never be able to use
|
||||
Optional's assignment without explicitly handling the previous initialization
|
||||
state unless your code is capable of functioning whether after the assignment,
|
||||
<code class="computeroutput"><span class="identifier">a</span></code> aliases the same object
|
||||
as <code class="computeroutput"><span class="identifier">b</span></code> or not.
|
||||
</p>
|
||||
<p>
|
||||
That is, you would have to discriminate in order to be consistent.
|
||||
</p>
|
||||
<p>
|
||||
If in your code rebinding to another object is not an option, then it is
|
||||
very likely that binding for the first time isn't either. In such case, assignment
|
||||
to an <span class="emphasis"><em>uninitialized </em></span> <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">&></span></code>
|
||||
shall be prohibited. It is quite possible that in such a scenario it is a
|
||||
precondition that the lvalue must be already initialized. If it isn't, then
|
||||
binding for the first time is OK while rebinding is not which is IMO very
|
||||
unlikely. In such a scenario, you can assign the value itself directly, as
|
||||
in:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">assert</span><span class="special">(!!</span><span class="identifier">opt</span><span class="special">);</span>
|
||||
<span class="special">*</span><span class="identifier">opt</span><span class="special">=</span><span class="identifier">value</span><span class="special">;</span>
|
||||
</pre>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014 Andrzej Krzemieński<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
</div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="optional_references.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../../optional/tutorial.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="in_place_factories.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
61
doc/html/boost_optional/tutorial/type_requirements.html
Normal file
61
doc/html/boost_optional/tutorial/type_requirements.html
Normal file
@ -0,0 +1,61 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Type requirements</title>
|
||||
<link rel="stylesheet" href="../../../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||
<link rel="home" href="../../index.html" title="Boost.Optional">
|
||||
<link rel="up" href="../../optional/tutorial.html" title="Tutorial">
|
||||
<link rel="prev" href="exception_safety_guarantees.html" title="Exception Safety Guarantees">
|
||||
<link rel="next" href="../../optional/reference.html" title="Reference">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
|
||||
<td align="center"><a href="../../../../../../index.html">Home</a></td>
|
||||
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
|
||||
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
|
||||
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="exception_safety_guarantees.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../../optional/tutorial.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../../optional/reference.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><div><h3 class="title">
|
||||
<a name="boost_optional.tutorial.type_requirements"></a><a class="link" href="type_requirements.html" title="Type requirements">Type requirements</a>
|
||||
</h3></div></div></div>
|
||||
<p>
|
||||
At the very minimum for <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>
|
||||
to work with a minimum interface it is required that <code class="computeroutput"><span class="identifier">T</span></code>
|
||||
has a publicly accessible no-throw destructor. In that case you need to initialize
|
||||
the optional object with function <code class="computeroutput"><span class="identifier">emplace</span><span class="special">()</span></code> or use <span class="bold"><strong>InPlaceFactories</strong></span>.
|
||||
Additionally, if <code class="computeroutput"><span class="identifier">T</span></code> is <code class="computeroutput"><span class="identifier">Moveable</span></code>, <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>
|
||||
is also <code class="computeroutput"><span class="identifier">Moveable</span></code> and can
|
||||
be easily initialized from an rvalue of type <code class="computeroutput"><span class="identifier">T</span></code>
|
||||
and be passed by value. Additionally, if <code class="computeroutput"><span class="identifier">T</span></code>
|
||||
is <code class="computeroutput"><span class="identifier">Copyable</span></code>, <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code> is
|
||||
also <code class="computeroutput"><span class="identifier">Copyable</span></code> and can be
|
||||
easily initialized from an lvalue of type <code class="computeroutput"><span class="identifier">T</span></code>.
|
||||
</p>
|
||||
<p>
|
||||
<code class="computeroutput"><span class="identifier">T</span></code> <span class="underline">is
|
||||
not</span> required to be <a href="http://www.sgi.com/tech/stl/DefaultConstructible.html" target="_top">Default
|
||||
Constructible</a>.
|
||||
</p>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"></td>
|
||||
<td align="right"><div class="copyright-footer">Copyright © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014 Andrzej Krzemieński<p>
|
||||
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
|
||||
</p>
|
||||
</div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav">
|
||||
<a accesskey="p" href="exception_safety_guarantees.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../../optional/tutorial.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../../optional/reference.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -27,9 +27,17 @@
|
||||
<a name="boost_optional.type_requirements"></a><a class="link" href="type_requirements.html" title="Type requirements">Type requirements</a>
|
||||
</h2></div></div></div>
|
||||
<p>
|
||||
In general, <code class="computeroutput"><span class="identifier">T</span></code> must be <code class="computeroutput"><span class="identifier">MoveConstructible</span></code> and have a no-throw destructor.
|
||||
The <code class="computeroutput"><span class="identifier">MoveConstructible</span></code> requirement
|
||||
is not needed if <span class="bold"><strong>InPlaceFactories</strong></span> are used.
|
||||
At the very minimum for <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>
|
||||
to work with a minimum interface it is required that <code class="computeroutput"><span class="identifier">T</span></code>
|
||||
has a publicly accessible no-throw destructor. In that case you need to initialize
|
||||
the optional object with function <code class="computeroutput"><span class="identifier">emplace</span><span class="special">()</span></code> or use <span class="bold"><strong>InPlaceFactories</strong></span>.
|
||||
Additionally, if <code class="computeroutput"><span class="identifier">T</span></code> is <code class="computeroutput"><span class="identifier">Moveable</span></code>, <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code>
|
||||
is also <code class="computeroutput"><span class="identifier">Moveable</span></code> and can be
|
||||
easily initialized from an rvalue of type <code class="computeroutput"><span class="identifier">T</span></code>
|
||||
and be passed by value. Additionally, if <code class="computeroutput"><span class="identifier">T</span></code>
|
||||
is <code class="computeroutput"><span class="identifier">Copyable</span></code>, <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">></span></code> is
|
||||
also <code class="computeroutput"><span class="identifier">Copyable</span></code> and can be easily
|
||||
initialized from an lvalue of type <code class="computeroutput"><span class="identifier">T</span></code>.
|
||||
</p>
|
||||
<p>
|
||||
<code class="computeroutput"><span class="identifier">T</span></code> <span class="underline">is
|
||||
|
@ -1,11 +1,11 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
|
||||
<title>Chapter 1. Boost.Optional</title>
|
||||
<title>Boost.Optional</title>
|
||||
<link rel="stylesheet" href="../../../../doc/src/boostbook.css" type="text/css">
|
||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||
<link rel="home" href="index.html" title="Chapter 1. Boost.Optional">
|
||||
<link rel="next" href="boost_optional/motivation.html" title="Motivation">
|
||||
<link rel="home" href="index.html" title="Boost.Optional">
|
||||
<link rel="next" href="boost_optional/quick_start.html" title="Quick Start">
|
||||
</head>
|
||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||
<table cellpadding="2" width="100%"><tr>
|
||||
@ -17,11 +17,11 @@
|
||||
<td align="center"><a href="../../../../more/index.htm">More</a></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav"><a accesskey="n" href="boost_optional/motivation.html"><img src="../../../../doc/src/images/next.png" alt="Next"></a></div>
|
||||
<div class="spirit-nav"><a accesskey="n" href="boost_optional/quick_start.html"><img src="../../../../doc/src/images/next.png" alt="Next"></a></div>
|
||||
<div class="chapter">
|
||||
<div class="titlepage"><div>
|
||||
<div><h2 class="title">
|
||||
<a name="optional"></a>Chapter 1. Boost.Optional</h2></div>
|
||||
<a name="optional"></a>Boost.Optional</h2></div>
|
||||
<div><div class="author"><h3 class="author">
|
||||
<span class="firstname">Fernando Luis</span> <span class="surname">Cacciola Carballal</span>
|
||||
</h3></div></div>
|
||||
@ -38,39 +38,48 @@
|
||||
<p><b>Table of Contents</b></p>
|
||||
<dl class="toc">
|
||||
<dt><span class="section"><a href="index.html#optional.introduction">Introduction</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_optional/motivation.html">Motivation</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_optional/development.html">Development</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_optional/quick_start.html">Quick Start</a></span></dt>
|
||||
<dd><dl>
|
||||
<dt><span class="section"><a href="boost_optional/development.html#boost_optional.development.the_models">The models</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_optional/development.html#boost_optional.development.the_semantics">The semantics</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_optional/development.html#boost_optional.development.the_interface">The Interface</a></span></dt>
|
||||
</dl></dd>
|
||||
<dt><span class="section"><a href="boost_optional/synopsis.html">Synopsis</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_optional/detailed_semantics.html">Detailed Semantics</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_optional/examples.html">Examples</a></span></dt>
|
||||
<dd><dl>
|
||||
<dt><span class="section"><a href="boost_optional/examples.html#boost_optional.examples.optional_return_values">Optional
|
||||
<dt><span class="section"><a href="boost_optional/quick_start.html#boost_optional.quick_start.optional_return_values">Optional
|
||||
return values</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_optional/examples.html#boost_optional.examples.optional_local_variables">Optional
|
||||
local variables</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_optional/examples.html#boost_optional.examples.optional_data_members">Optional
|
||||
<dt><span class="section"><a href="boost_optional/quick_start/optional_automatic_variables.html">Optional
|
||||
automatic variables</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_optional/quick_start/optional_data_members.html">Optional
|
||||
data members</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_optional/examples.html#boost_optional.examples.bypassing_expensive_unnecessary_default_construction">Bypassing
|
||||
expensive unnecessary default construction</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_optional/quick_start/bypassing_unnecessary_default_construction.html">Bypassing
|
||||
unnecessary default construction</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_optional/quick_start/storage_in_containers.html">Storage
|
||||
in containers</a></span></dt>
|
||||
</dl></dd>
|
||||
<dt><span class="section"><a href="optional/tutorial.html">Tutorial</a></span></dt>
|
||||
<dd><dl>
|
||||
<dt><span class="section"><a href="optional/tutorial.html#boost_optional.tutorial.motivation">Motivation</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_optional/tutorial/design_overview.html">Design Overview</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_optional/tutorial/optional_references.html">Optional
|
||||
references</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_optional/tutorial/rebinding_semantics_for_assignment_of_optional_references.html">Rebinding
|
||||
semantics for assignment of optional references</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_optional/tutorial/in_place_factories.html">In-Place
|
||||
Factories</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_optional/tutorial/a_note_about_optional_bool_.html">A
|
||||
note about optional<bool></a></span></dt>
|
||||
<dt><span class="section"><a href="boost_optional/tutorial/exception_safety_guarantees.html">Exception
|
||||
Safety Guarantees</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_optional/tutorial/type_requirements.html">Type requirements</a></span></dt>
|
||||
</dl></dd>
|
||||
<dt><span class="section"><a href="optional/reference.html">Reference</a></span></dt>
|
||||
<dd><dl>
|
||||
<dt><span class="section"><a href="optional/reference.html#boost_optional.reference.synopsis">Synopsis</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_optional/reference/detailed_semantics.html">Detailed
|
||||
Semantics</a></span></dt>
|
||||
</dl></dd>
|
||||
<dt><span class="section"><a href="boost_optional/optional_references.html">Optional references</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_optional/rebinding_semantics_for_assignment_of_optional_references.html">Rebinding
|
||||
semantics for assignment of optional references</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_optional/in_place_factories.html">In-Place Factories</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_optional/a_note_about_optional_bool_.html">A note about
|
||||
optional<bool></a></span></dt>
|
||||
<dt><span class="section"><a href="boost_optional/exception_safety_guarantees.html">Exception Safety
|
||||
Guarantees</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_optional/type_requirements.html">Type requirements</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_optional/dependencies_and_portability.html">Dependencies
|
||||
and Portability</a></span></dt>
|
||||
<dd><dl><dt><span class="section"><a href="boost_optional/dependencies_and_portability.html#boost_optional.dependencies_and_portability.optional_reference_binding">Optional
|
||||
Reference Binding</a></span></dt></dl></dd>
|
||||
<dd><dl>
|
||||
<dt><span class="section"><a href="boost_optional/dependencies_and_portability.html#boost_optional.dependencies_and_portability.dependencies">Dependencies</a></span></dt>
|
||||
<dt><span class="section"><a href="boost_optional/dependencies_and_portability/optional_reference_binding.html">Optional
|
||||
Reference Binding</a></span></dt>
|
||||
</dl></dd>
|
||||
<dt><span class="section"><a href="boost_optional/acknowledgments.html">Acknowledgments</a></span></dt>
|
||||
</dl>
|
||||
</div>
|
||||
@ -79,23 +88,51 @@
|
||||
<a name="optional.introduction"></a><a class="link" href="index.html#optional.introduction" title="Introduction">Introduction</a>
|
||||
</h2></div></div></div>
|
||||
<p>
|
||||
This library can be used to represent 'optional' (or 'nullable') objects that
|
||||
can be safely passed by value:
|
||||
Class template <code class="computeroutput"><span class="identifier">optional</span></code> is
|
||||
a wrapper for representing 'optional' (or 'nullable') objects who may not (yet)
|
||||
contain a valid value. Optional objects offer full value semantics; they are
|
||||
good for passing by value and usage inside STL containers. This is a header-only
|
||||
library.
|
||||
</p>
|
||||
<pre class="programlisting"><span class="identifier">optional</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">readInt</span><span class="special">();</span> <span class="comment">// this function may return either an int or a not-an-int</span>
|
||||
<h4>
|
||||
<a name="optional.introduction.h0"></a>
|
||||
<span class="phrase"><a name="optional.introduction.problem"></a></span><a class="link" href="index.html#optional.introduction.problem">Problem</a>
|
||||
</h4>
|
||||
<p>
|
||||
Suppose we want to read a parameter form a config file which represents some
|
||||
integral value, let's call it <code class="computeroutput"><span class="string">"MaxValue"</span></code>.
|
||||
It is possible that this parameter is not specified; such situation is no error.
|
||||
It is valid to not specify the parameter and in that case the program is supposed
|
||||
to behave slightly different. Also suppose that any possible value of type
|
||||
<code class="computeroutput"><span class="keyword">int</span></code> is a valid value for <code class="computeroutput"><span class="string">"MaxValue"</span></code>, so we cannot jut use <code class="computeroutput"><span class="special">-</span><span class="number">1</span></code> to represent
|
||||
the absence of the parameter in the config file.
|
||||
</p>
|
||||
<h4>
|
||||
<a name="optional.introduction.h1"></a>
|
||||
<span class="phrase"><a name="optional.introduction.solution"></a></span><a class="link" href="index.html#optional.introduction.solution">Solution</a>
|
||||
</h4>
|
||||
<p>
|
||||
This is how you solve it with <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span></code>:
|
||||
</p>
|
||||
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">optional</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
|
||||
|
||||
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">optional</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">oi</span> <span class="special">=</span> <span class="identifier">readInt</span><span class="special">())</span> <span class="comment">// did I get a real int</span>
|
||||
<span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"my int is: "</span> <span class="special"><<</span> <span class="special">*</span><span class="identifier">oi</span><span class="special">;</span> <span class="comment">// use my int</span>
|
||||
<span class="keyword">else</span>
|
||||
<span class="identifier">cout</span> <span class="special"><<</span> <span class="string">"I have no int"</span><span class="special">;</span>
|
||||
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">getConfigParam</span><span class="special">(</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span> <span class="identifier">name</span><span class="special">);</span> <span class="comment">// return either an int or a `not-an-int`</span>
|
||||
|
||||
<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
|
||||
<span class="special">{</span>
|
||||
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span><span class="special"><</span><span class="keyword">int</span><span class="special">></span> <span class="identifier">oi</span> <span class="special">=</span> <span class="identifier">getConfigParam</span><span class="special">(</span><span class="string">"MaxValue"</span><span class="special">))</span> <span class="comment">// did I get a real int?</span>
|
||||
<span class="identifier">runWithMax</span><span class="special">(*</span><span class="identifier">oi</span><span class="special">);</span> <span class="comment">// use my int</span>
|
||||
<span class="keyword">else</span>
|
||||
<span class="identifier">runWithNoMax</span><span class="special">();</span>
|
||||
<span class="special">}</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||
<td align="left"><p><small>Last revised: May 13, 2014 at 19:18:04 GMT</small></p></td>
|
||||
<td align="left"><p><small>Last revised: June 05, 2014 at 22:46:34 GMT</small></p></td>
|
||||
<td align="right"><div class="copyright-footer"></div></td>
|
||||
</tr></table>
|
||||
<hr>
|
||||
<div class="spirit-nav"><a accesskey="n" href="boost_optional/motivation.html"><img src="../../../../doc/src/images/next.png" alt="Next"></a></div>
|
||||
<div class="spirit-nav"><a accesskey="n" href="boost_optional/quick_start.html"><img src="../../../../doc/src/images/next.png" alt="Next"></a></div>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,375 +0,0 @@
|
||||
|
||||
[section Optional references]
|
||||
|
||||
This library allows 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:
|
||||
|
||||
* Converting constructors
|
||||
* Converting assignment
|
||||
* InPlace construction
|
||||
* InPlace assignment
|
||||
* Value-access via pointer
|
||||
|
||||
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:
|
||||
|
||||
* Copies of `optional<T&>` will copy the references but all these references
|
||||
will nonetheless refer to the same object.
|
||||
* Value-access will actually provide access to the referenced object
|
||||
rather than the reference itself.
|
||||
|
||||
[warning On compilers that do not conform to Standard C++ rules of reference binding, operations on optional references might give adverse results: rather than binding a reference to a designated object they may create an unexpected temporary and bind to it. For more details see [link boost_optional.dependencies_and_portability.optional_reference_binding Dependencies and Portability section].]
|
||||
|
||||
[heading Rvalue references]
|
||||
|
||||
Rvalue references and lvalue references to const have the ability in C++ to extend the life time of a temporary they bind to. Optional references do not have this capability, therefore to avoid surprising effects it is not possible to initialize an optional references from a temporary. Optional rvalue references are disabled altogether. Also, the initialization and assignment of an optional reference to const from rvalue reference is disabled.
|
||||
|
||||
const int& i = 1; // legal
|
||||
optional<const int&> oi = 1; // illegal
|
||||
|
||||
[endsect]
|
||||
|
||||
[section Rebinding semantics for assignment of optional references]
|
||||
|
||||
If you assign to an ['uninitialized ] `optional<T&>` the effect is to bind (for
|
||||
the first time) to the object. Clearly, there is no other choice.
|
||||
|
||||
int x = 1 ;
|
||||
int& rx = x ;
|
||||
optional<int&> ora ;
|
||||
optional<int&> orb(x) ;
|
||||
ora = orb ; // now 'ora' is bound to 'x' through 'rx'
|
||||
*ora = 2 ; // Changes value of 'x' through 'ora'
|
||||
assert(x==2);
|
||||
|
||||
If you assign to a bare C++ reference, the assignment is forwarded to the
|
||||
referenced object; its value changes but the reference is never rebound.
|
||||
|
||||
int a = 1 ;
|
||||
int& ra = a ;
|
||||
int b = 2 ;
|
||||
int& rb = b ;
|
||||
ra = rb ; // Changes the value of 'a' to 'b'
|
||||
assert(a==b);
|
||||
b = 3 ;
|
||||
assert(ra!=b); // 'ra' is not rebound to 'b'
|
||||
|
||||
Now, if you assign to an ['initialized ] `optional<T&>`, the effect is to
|
||||
[*rebind] to the new object instead of assigning the referee. This is unlike
|
||||
bare C++ references.
|
||||
|
||||
int a = 1 ;
|
||||
int b = 2 ;
|
||||
int& ra = a ;
|
||||
int& rb = b ;
|
||||
optional<int&> ora(ra) ;
|
||||
optional<int&> orb(rb) ;
|
||||
ora = orb ; // 'ora' is rebound to 'b'
|
||||
*ora = 3 ; // Changes value of 'b' (not 'a')
|
||||
assert(a==1);
|
||||
assert(b==3);
|
||||
|
||||
[heading Rationale]
|
||||
|
||||
Rebinding semantics for the assignment of ['initialized ] `optional` references has
|
||||
been chosen to provide [*consistency among initialization states] even at the
|
||||
expense of lack of consistency with the semantics of bare C++ references.
|
||||
It is true that `optional<U>` strives to behave as much as possible as `U`
|
||||
does whenever it is initialized; but in the case when `U` is `T&`, doing so would
|
||||
result in inconsistent behavior w.r.t to the lvalue initialization state.
|
||||
|
||||
Imagine `optional<T&>` forwarding assignment to the referenced object (thus
|
||||
changing the referenced object value but not rebinding), and consider the
|
||||
following code:
|
||||
|
||||
optional<int&> a = get();
|
||||
int x = 1 ;
|
||||
int& rx = x ;
|
||||
optional<int&> b(rx);
|
||||
a = b ;
|
||||
|
||||
What does the assignment do?
|
||||
|
||||
If `a` is ['uninitialized], the answer is clear: it binds to `x` (we now have
|
||||
another reference to `x`).
|
||||
But what if `a` is already ['initialized]? it would change the value of the
|
||||
referenced object (whatever that is); which is inconsistent with the other
|
||||
possible case.
|
||||
|
||||
If `optional<T&>` would assign just like `T&` does, you would never be able to
|
||||
use Optional's assignment without explicitly handling the previous
|
||||
initialization state unless your code is capable of functioning whether
|
||||
after the assignment, `a` aliases the same object as `b` or not.
|
||||
|
||||
That is, you would have to discriminate in order to be consistent.
|
||||
|
||||
If in your code rebinding to another object is not an option, then it is very
|
||||
likely that binding for the first time isn't either. In such case, assignment
|
||||
to an ['uninitialized ] `optional<T&>` shall be prohibited. It is quite possible
|
||||
that in such a scenario it is a precondition that the lvalue must be already
|
||||
initialized. If it isn't, then binding for the first time is OK
|
||||
while rebinding is not which is IMO very unlikely.
|
||||
In such a scenario, you can assign the value itself directly, as in:
|
||||
|
||||
assert(!!opt);
|
||||
*opt=value;
|
||||
|
||||
[endsect]
|
||||
|
||||
[section 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 scheme, 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 family 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 family 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>(123,"hello")) ;
|
||||
}
|
||||
|
||||
The factories are divided in two groups:
|
||||
|
||||
* [_TypedInPlaceFactories]: those which take the target type as a primary
|
||||
template parameter.
|
||||
* [_InPlaceFactories]: those with a template `construct(void*)` member
|
||||
function taking the target type.
|
||||
|
||||
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< class InPlaceFactory >
|
||||
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__
|
||||
|
||||
[endsect]
|
||||
|
||||
[section 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__— 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, although `optional<>` provides a contextual conversion to `bool` in C++11,
|
||||
this falls back to an implicit conversion on older compilers. 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).
|
||||
|
||||
Third, mixed comparisons with `bool` work differently than similar mixed comparisons between pointers and `bool`, so the results might surprise you:
|
||||
|
||||
optional<bool> oEmpty(none), oTrue(true), oFalse(false);
|
||||
|
||||
if (oEmpty == none); // renders true
|
||||
if (oEmpty == false); // renders false!
|
||||
if (oEmpty == true); // renders false!
|
||||
|
||||
if (oFalse == none); // renders false
|
||||
if (oFalse == false); // renders true!
|
||||
if (oFalse == true); // renders false
|
||||
|
||||
if (oTrue == none); // renders false
|
||||
if (oTrue == false); // renders false
|
||||
if (oTrue == true); // renders true
|
||||
|
||||
In other words, for `optional<>`, the following assertion does not hold:
|
||||
|
||||
assert((opt == false) == (!opt));
|
||||
[endsect]
|
||||
|
||||
[section Exception Safety Guarantees]
|
||||
|
||||
This library assumes that `T`'s destructor does not throw exceptions. If it does, the behaviour of many operations on `optional<T>` is undefined.
|
||||
|
||||
The following mutating operations never throw exceptions:
|
||||
|
||||
* `optional<T>::operator= ( none_t ) noexcept`
|
||||
* `optional<T>::reset() noexcept`
|
||||
|
||||
In addition, the following constructors and the destructor never throw exceptions:
|
||||
|
||||
* `optional<T>::optional() noexcept`
|
||||
* `optional<T>::optional( none_t ) noexcept`
|
||||
|
||||
|
||||
Regarding the following assignment functions:
|
||||
|
||||
* `optional<T>::operator= ( optional<T> const& )`
|
||||
* `optional<T>::operator= ( T const& )`
|
||||
* `template<class U> optional<T>::operator= ( optional<U> const& )`
|
||||
* `template<class InPlaceFactory> optional<T>::operator= ( InPlaceFactory const& )`
|
||||
* `template<class TypedInPlaceFactory> optional<T>::operator= ( TypedInPlaceFactory const& ) `
|
||||
* `optional<T>::reset( T const& )`
|
||||
|
||||
They forward calls to the corresponding `T`'s constructors or assignments (depending on whether the optional object is initialized or not); so if both `T`'s constructor and the assignment provide strong exception safety guarantee, `optional<T>`'s assignment also provides strong exception safety guarantee; otherwise we only get the basic guarantee. Additionally, if both involved `T`'s constructor and the assignment never throw, `optional<T>`'s assignment also never throws.
|
||||
|
||||
Unless `T`'s constructor or assignment throws, `optional<T>` does not throw anything else on its own. A throw during assignment never changes the initialization state of any optional object involved:
|
||||
|
||||
|
||||
optional<T> opt1(val1);
|
||||
optional<T> opt2(val2);
|
||||
assert(opt1);
|
||||
assert(opt2);
|
||||
|
||||
try
|
||||
{
|
||||
opt1 = opt2; // throws
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
assert(opt1);
|
||||
assert(opt2);
|
||||
}
|
||||
|
||||
This also applies to move assignments/constructors. However, move operations are made no-throw more often.
|
||||
|
||||
[heading Swap]
|
||||
|
||||
Unless `swap` on optional is customized, its primary implementation forwards calls to `T`'s `swap` or move constructor (depending on the initialization state of the optional objects). Thus, if both `T`'s `swap` and move constructor never throw, `swap` on `optional<T>` never throws. similarly, if both `T`'s `swap` and move constructor offer strong guarantee, `swap` on `optional<T>` also offers a strong guarantee.
|
||||
|
||||
In case `swap` on optional is customized, the call to `T`'s move constructor are replaced with the calls to `T`'s default constructor followed by `swap`. (This is more useful on older compilers that do not support move semantics, when one wants to acheive stronger exception safety guarantees.) In this case the exception safety guarantees for `swap` are reliant on the guarantees of `T`'s `swap` and default constructor
|
||||
[endsect]
|
||||
|
||||
[section Type requirements]
|
||||
|
||||
In general, `T` must be `MoveConstructible` and have a no-throw destructor.
|
||||
The `MoveConstructible` requirement is not needed if [*InPlaceFactories] are used.
|
||||
|
||||
`T` [_is not] required to be __SGI_DEFAULT_CONSTRUCTIBLE__.
|
||||
|
||||
[endsect]
|
||||
|
||||
|
@ -1,28 +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/libs/optional for documentation.
|
||||
//
|
||||
// You are welcome to contact the author at:
|
||||
// fernando_cacciola@hotmail.com
|
||||
//
|
||||
#ifndef BOOST_DETAIL_NONE_T_17SEP2003_HPP
|
||||
#define BOOST_DETAIL_NONE_T_17SEP2003_HPP
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace detail {
|
||||
|
||||
struct none_helper{};
|
||||
|
||||
typedef int none_helper::*none_t ;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
|
28
include/boost/optional/bad_optional_access.hpp
Normal file
28
include/boost/optional/bad_optional_access.hpp
Normal file
@ -0,0 +1,28 @@
|
||||
// Copyright (C) 2014, Andrzej Krzemienski.
|
||||
//
|
||||
// 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/libs/optional for documentation.
|
||||
//
|
||||
// You are welcome to contact the author at:
|
||||
// akrzemi1@gmail.com
|
||||
//
|
||||
#ifndef BOOST_BAD_OPTIONAL_ACCESS_22MAY2014_HPP
|
||||
#define BOOST_BAD_OPTIONAL_ACCESS_22MAY2014_HPP
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
namespace boost {
|
||||
|
||||
class bad_optional_access : public std::logic_error
|
||||
{
|
||||
public:
|
||||
explicit bad_optional_access(const std::string& what_arg) : std::logic_error(what_arg) {}
|
||||
explicit bad_optional_access(const char* what_arg) : std::logic_error(what_arg) {}
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
@ -23,7 +23,9 @@
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/optional/bad_optional_access.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/type.hpp>
|
||||
#include <boost/type_traits/alignment_of.hpp>
|
||||
#include <boost/type_traits/has_nothrow_constructor.hpp>
|
||||
@ -149,7 +151,14 @@ struct types_when_isnt_ref
|
||||
typedef T & reference_type ;
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
typedef T && rval_reference_type ;
|
||||
typedef T && reference_type_of_temporary_wrapper;
|
||||
#ifdef BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
|
||||
// GCC 4.4 has support for an early draft of rvalue references. The conforming version below
|
||||
// causes warnings about returning references to a temporary.
|
||||
static T&& move(T&& r) { return r; }
|
||||
#else
|
||||
static rval_reference_type move(reference_type r) { return boost::move(r); }
|
||||
#endif
|
||||
#endif
|
||||
typedef T const* pointer_const_type ;
|
||||
typedef T * pointer_type ;
|
||||
@ -165,6 +174,7 @@ struct types_when_is_ref
|
||||
typedef raw_type& reference_type ;
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
typedef BOOST_DEDUCED_TYPENAME remove_const<raw_type>::type&& rval_reference_type ;
|
||||
typedef raw_type& reference_type_of_temporary_wrapper;
|
||||
static reference_type move(reference_type r) { return r; }
|
||||
#endif
|
||||
typedef raw_type* pointer_const_type ;
|
||||
@ -219,6 +229,7 @@ class optional_base : public optional_tag
|
||||
typedef BOOST_DEDUCED_TYPENAME types::reference_const_type reference_const_type ;
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
typedef BOOST_DEDUCED_TYPENAME types::rval_reference_type rval_reference_type ;
|
||||
typedef BOOST_DEDUCED_TYPENAME types::reference_type_of_temporary_wrapper reference_type_of_temporary_wrapper ;
|
||||
#endif
|
||||
typedef BOOST_DEDUCED_TYPENAME types::pointer_type pointer_type ;
|
||||
typedef BOOST_DEDUCED_TYPENAME types::pointer_const_type pointer_const_type ;
|
||||
@ -433,11 +444,11 @@ class optional_base : public optional_tag
|
||||
|
||||
public :
|
||||
|
||||
// Destroys the current value, if any, leaving this UNINITIALIZED
|
||||
// **DEPPRECATED** Destroys the current value, if any, leaving this UNINITIALIZED
|
||||
// No-throw (assuming T::~T() doesn't)
|
||||
void reset() BOOST_NOEXCEPT { destroy(); }
|
||||
|
||||
// Replaces the current value -if any- with 'val'
|
||||
// **DEPPRECATED** Replaces the current value -if any- with 'val'
|
||||
void reset ( argument_type val ) { assign(val); }
|
||||
|
||||
// Returns a pointer to the value if this is initialized, otherwise,
|
||||
@ -452,14 +463,26 @@ class optional_base : public optional_tag
|
||||
|
||||
void construct ( argument_type val )
|
||||
{
|
||||
new (m_storage.address()) internal_type(val) ;
|
||||
::new (m_storage.address()) internal_type(val) ;
|
||||
m_initialized = true ;
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
void construct ( rval_reference_type val )
|
||||
{
|
||||
new (m_storage.address()) internal_type( types::move(val) ) ;
|
||||
::new (m_storage.address()) internal_type( types::move(val) ) ;
|
||||
m_initialized = true ;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (!defined BOOST_NO_CXX11_RVALUE_REFERENCES) && (!defined BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
// Constructs in-place
|
||||
// upon exception *this is always uninitialized
|
||||
template<class... Args>
|
||||
void emplace_assign ( Args&&... args )
|
||||
{
|
||||
destroy();
|
||||
::new (m_storage.address()) internal_type( boost::forward<Args>(args)... );
|
||||
m_initialized = true ;
|
||||
}
|
||||
#endif
|
||||
@ -499,6 +522,7 @@ class optional_base : public optional_tag
|
||||
destroy();
|
||||
construct(factory,tag);
|
||||
}
|
||||
|
||||
#else
|
||||
// Constructs in-place using the given factory
|
||||
template<class Expr>
|
||||
@ -704,6 +728,7 @@ class optional : public optional_detail::optional_base<T>
|
||||
typedef BOOST_DEDUCED_TYPENAME base::reference_const_type reference_const_type ;
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
typedef BOOST_DEDUCED_TYPENAME base::rval_reference_type rval_reference_type ;
|
||||
typedef BOOST_DEDUCED_TYPENAME base::reference_type_of_temporary_wrapper reference_type_of_temporary_wrapper ;
|
||||
#endif
|
||||
typedef BOOST_DEDUCED_TYPENAME base::pointer_type pointer_type ;
|
||||
typedef BOOST_DEDUCED_TYPENAME base::pointer_const_type pointer_const_type ;
|
||||
@ -899,6 +924,16 @@ class optional : public optional_detail::optional_base<T>
|
||||
this->assign( none_ ) ;
|
||||
return *this ;
|
||||
}
|
||||
|
||||
#if (!defined BOOST_NO_CXX11_RVALUE_REFERENCES) && (!defined BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
// Constructs in-place
|
||||
// upon exception *this is always uninitialized
|
||||
template<class... Args>
|
||||
void emplace ( Args&&... args )
|
||||
{
|
||||
this->emplace_assign( boost::forward<Args>(args)... );
|
||||
}
|
||||
#endif
|
||||
|
||||
void swap( optional & arg )
|
||||
BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value && ::boost::is_nothrow_move_assignable<T>::value)
|
||||
@ -927,9 +962,74 @@ class optional : public optional_detail::optional_base<T>
|
||||
// Returns a reference to the value if this is initialized, otherwise,
|
||||
// the behaviour is UNDEFINED
|
||||
// No-throw
|
||||
#ifndef BOOST_NO_CXX11_REF_QUALIFIERS
|
||||
reference_const_type operator *() const& { return this->get() ; }
|
||||
reference_type operator *() & { return this->get() ; }
|
||||
reference_type_of_temporary_wrapper operator *() && { return boost::move(this->get()) ; }
|
||||
#else
|
||||
reference_const_type operator *() const { return this->get() ; }
|
||||
reference_type operator *() { return this->get() ; }
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_NO_CXX11_REF_QUALIFIERS
|
||||
reference_const_type value() const&
|
||||
{
|
||||
if (this->is_initialized())
|
||||
return this->get() ;
|
||||
else
|
||||
throw_exception(bad_optional_access("Attempted to access the value of an uninitialized optional object."));
|
||||
}
|
||||
|
||||
reference_type value() &
|
||||
{
|
||||
if (this->is_initialized())
|
||||
return this->get() ;
|
||||
else
|
||||
throw_exception(bad_optional_access("Attempted to access the value of an uninitialized optional object."));
|
||||
}
|
||||
|
||||
reference_type_of_temporary_wrapper value() &&
|
||||
{
|
||||
if (this->is_initialized())
|
||||
return boost::move(this->get()) ;
|
||||
else
|
||||
throw_exception(bad_optional_access("Attempted to access the value of an uninitialized optional object."));
|
||||
}
|
||||
#else
|
||||
reference_const_type value() const
|
||||
{
|
||||
if (this->is_initialized())
|
||||
return this->get() ;
|
||||
else
|
||||
throw_exception(bad_optional_access("Attempted to access the value of an uninitialized optional object."));
|
||||
}
|
||||
|
||||
reference_type value()
|
||||
{
|
||||
if (this->is_initialized())
|
||||
return this->get() ;
|
||||
else
|
||||
throw_exception(bad_optional_access("Attempted to access the value of an uninitialized optional object."));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_NO_CXX11_REF_QUALIFIERS
|
||||
template <class U>
|
||||
value_type value_or ( U&& v ) const&
|
||||
{ return this->is_initialized() ? get() : static_cast<value_type>(boost::forward<U>(v)); }
|
||||
|
||||
template <class U>
|
||||
value_type value_or ( U&& v ) &&
|
||||
{ return this->is_initialized() ? boost::move(get()) : static_cast<value_type>(boost::forward<U>(v)); }
|
||||
#elif !defined BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
template <class U>
|
||||
value_type value_or ( U&& v ) const
|
||||
{ return this->is_initialized() ? get() : static_cast<value_type>(boost::forward<U>(v)); }
|
||||
#else
|
||||
template <class U>
|
||||
value_type value_or ( U const& v ) const { return this->is_initialized() ? get() : static_cast<value_type>(v); }
|
||||
#endif
|
||||
|
||||
bool operator!() const BOOST_NOEXCEPT { return !this->is_initialized() ; }
|
||||
|
||||
BOOST_EXPLICIT_OPERATOR_BOOL()
|
||||
|
@ -11,11 +11,9 @@
|
||||
//
|
||||
// Revisions:
|
||||
// 10 May 2008 (added swap related forward declaration) Niels Dekker
|
||||
// 17 Apr 2014 (added noexcept) Andrzej Krzemienski
|
||||
//
|
||||
#ifndef BOOST_OPTIONAL_OPTIONAL_FWD_FLC_19NOV2002_HPP
|
||||
#define BOOST_OPTIONAL_OPTIONAL_FWD_FLC_19NOV2002_HPP
|
||||
#include <boost/config.hpp>
|
||||
|
||||
|
||||
namespace boost {
|
||||
|
@ -23,6 +23,8 @@ import testing ;
|
||||
[ run optional_test_io.cpp ]
|
||||
[ run optional_test_move.cpp ]
|
||||
[ run optional_test_equals_none.cpp ]
|
||||
[ run optional_test_value_access.cpp ]
|
||||
[ run optional_test_emplace.cpp ]
|
||||
[ compile-fail optional_test_fail1.cpp ]
|
||||
[ compile-fail optional_test_fail3a.cpp ]
|
||||
[ compile-fail optional_test_fail3b.cpp ]
|
||||
|
@ -37,7 +37,7 @@ void assertion_failed (char const * expr, char const * func, char const * file,
|
||||
|
||||
using boost::optional ;
|
||||
|
||||
template<class T> inline void unused_variable ( T ) {}
|
||||
template<class T> inline void unused_variable ( const T& ) {}
|
||||
|
||||
#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
|
||||
using boost::swap ;
|
||||
|
169
test/optional_test_emplace.cpp
Normal file
169
test/optional_test_emplace.cpp
Normal file
@ -0,0 +1,169 @@
|
||||
// Copyright (C) 2014 Andrzej Krzemienski.
|
||||
//
|
||||
// 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:
|
||||
// akrzemi1@gmail.com
|
||||
//
|
||||
// Revisions:
|
||||
//
|
||||
#include<iostream>
|
||||
#include<stdexcept>
|
||||
#include<string>
|
||||
|
||||
#define BOOST_ENABLE_ASSERT_HANDLER
|
||||
|
||||
#include "boost/bind/apply.hpp" // Included just to test proper interaction with boost::apply<> as reported by Daniel Wallin
|
||||
#include "boost/mpl/bool.hpp"
|
||||
#include "boost/mpl/bool_fwd.hpp" // For mpl::true_ and mpl::false_
|
||||
#include "boost/static_assert.hpp"
|
||||
|
||||
#include "boost/optional/optional.hpp"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#include "boost/none.hpp"
|
||||
|
||||
#include "boost/test/minimal.hpp"
|
||||
|
||||
#include "optional_test_common.cpp"
|
||||
|
||||
//#ifndef BOOST_OPTIONAL_NO_CONVERTING_ASSIGNMENT
|
||||
//#ifndef BOOST_OPTIONAL_NO_CONVERTING_COPY_CTOR
|
||||
|
||||
#if (!defined BOOST_NO_CXX11_RVALUE_REFERENCES) && (!defined BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
class Guard
|
||||
{
|
||||
public:
|
||||
int which_ctor;
|
||||
Guard () : which_ctor(0) { }
|
||||
Guard (int&, double&&) : which_ctor(1) { }
|
||||
Guard (int&&, double&) : which_ctor(2) { }
|
||||
Guard (int&&, double&&) : which_ctor(3) { }
|
||||
Guard (int&, double&) : which_ctor(4) { }
|
||||
Guard (std::string const&) : which_ctor(5) { }
|
||||
Guard (std::string &) : which_ctor(6) { }
|
||||
Guard (std::string &&) : which_ctor(7) { }
|
||||
private:
|
||||
Guard(Guard&&);
|
||||
Guard(Guard const&);
|
||||
void operator=(Guard &&);
|
||||
void operator=(Guard const&);
|
||||
};
|
||||
|
||||
struct Thrower
|
||||
{
|
||||
Thrower(bool throw_) { if (throw_) throw int(); }
|
||||
|
||||
private:
|
||||
Thrower(Thrower const&);
|
||||
Thrower(Thrower&&);
|
||||
};
|
||||
|
||||
struct ThrowOnMove
|
||||
{
|
||||
ThrowOnMove(ThrowOnMove&&) { throw int(); }
|
||||
ThrowOnMove(ThrowOnMove const&) { throw int(); }
|
||||
ThrowOnMove(int){}
|
||||
};
|
||||
|
||||
void test_emplace()
|
||||
{
|
||||
int i = 0;
|
||||
double d = 0.0;
|
||||
const std::string cs;
|
||||
std::string ms;
|
||||
optional<Guard> o;
|
||||
|
||||
o.emplace();
|
||||
BOOST_CHECK(o);
|
||||
BOOST_CHECK(0 == o->which_ctor);
|
||||
|
||||
o.emplace(i, 2.0);
|
||||
BOOST_CHECK(o);
|
||||
BOOST_CHECK(1 == o->which_ctor);
|
||||
|
||||
o.emplace(1, d);
|
||||
BOOST_CHECK(o);
|
||||
BOOST_CHECK(2 == o->which_ctor);
|
||||
|
||||
o.emplace(1, 2.0);
|
||||
BOOST_CHECK(o);
|
||||
BOOST_CHECK(3 == o->which_ctor);
|
||||
|
||||
o.emplace(i, d);
|
||||
BOOST_CHECK(o);
|
||||
BOOST_CHECK(4 == o->which_ctor);
|
||||
|
||||
o.emplace(cs);
|
||||
BOOST_CHECK(o);
|
||||
BOOST_CHECK(5 == o->which_ctor);
|
||||
|
||||
o.emplace(ms);
|
||||
BOOST_CHECK(o);
|
||||
BOOST_CHECK(6 == o->which_ctor);
|
||||
|
||||
o.emplace(std::string());
|
||||
BOOST_CHECK(o);
|
||||
BOOST_CHECK(7 == o->which_ctor);
|
||||
}
|
||||
|
||||
void test_clear_on_throw()
|
||||
{
|
||||
optional<Thrower> ot;
|
||||
try {
|
||||
ot.emplace(false);
|
||||
BOOST_CHECK(ot);
|
||||
} catch(...) {
|
||||
BOOST_CHECK(false);
|
||||
}
|
||||
|
||||
try {
|
||||
ot.emplace(true);
|
||||
BOOST_CHECK(false);
|
||||
} catch(...) {
|
||||
BOOST_CHECK(!ot);
|
||||
}
|
||||
}
|
||||
|
||||
void test_no_moves_on_emplacement()
|
||||
{
|
||||
try {
|
||||
optional<ThrowOnMove> o;
|
||||
o.emplace(1);
|
||||
BOOST_CHECK(o);
|
||||
}
|
||||
catch (...) {
|
||||
BOOST_CHECK(false);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
int test_main( int, char* [] )
|
||||
{
|
||||
try
|
||||
{
|
||||
#if (!defined BOOST_NO_CXX11_RVALUE_REFERENCES) && (!defined BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
test_emplace();
|
||||
test_clear_on_throw();
|
||||
test_no_moves_on_emplacement();
|
||||
#endif
|
||||
}
|
||||
catch ( ... )
|
||||
{
|
||||
BOOST_ERROR("Unexpected Exception caught!");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
175
test/optional_test_value_access.cpp
Normal file
175
test/optional_test_value_access.cpp
Normal file
@ -0,0 +1,175 @@
|
||||
// Copyright (C) 2014 Andrzej Krzemienski.
|
||||
//
|
||||
// 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:
|
||||
// akrzemi1@gmail.com
|
||||
//
|
||||
// Revisions:
|
||||
//
|
||||
#include<iostream>
|
||||
#include<stdexcept>
|
||||
#include<string>
|
||||
|
||||
#define BOOST_ENABLE_ASSERT_HANDLER
|
||||
|
||||
#include "boost/bind/apply.hpp" // Included just to test proper interaction with boost::apply<> as reported by Daniel Wallin
|
||||
#include "boost/mpl/bool.hpp"
|
||||
#include "boost/mpl/bool_fwd.hpp" // For mpl::true_ and mpl::false_
|
||||
|
||||
#include "boost/optional/optional.hpp"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#include "boost/none.hpp"
|
||||
|
||||
#include "boost/test/minimal.hpp"
|
||||
|
||||
#include "optional_test_common.cpp"
|
||||
|
||||
struct IntWrapper
|
||||
{
|
||||
int _i;
|
||||
IntWrapper(int i) : _i(i) {}
|
||||
bool operator==(IntWrapper const& rhs) const { return _i == rhs._i; }
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
void test_function_value_or_for()
|
||||
{
|
||||
optional<T> oM0;
|
||||
const optional<T> oC0;
|
||||
optional<T> oM1(1);
|
||||
const optional<T> oC2(2);
|
||||
|
||||
BOOST_CHECK(oM0.value_or(5) == 5);
|
||||
BOOST_CHECK(oC0.value_or(5) == 5);
|
||||
BOOST_CHECK(oM1.value_or(5) == 1);
|
||||
BOOST_CHECK(oC2.value_or(5) == 2);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void test_function_value_for()
|
||||
{
|
||||
optional<T> o0;
|
||||
optional<T> o1(1);
|
||||
const optional<T> oC(2);
|
||||
|
||||
try
|
||||
{
|
||||
T& v = o1.value();
|
||||
BOOST_CHECK(v == 1);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
BOOST_CHECK(false);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
T const& v = oC.value();
|
||||
BOOST_CHECK(v == 2);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
BOOST_CHECK(false);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
T& v = o0.value();
|
||||
BOOST_CHECK(false);
|
||||
unused_variable(v);
|
||||
}
|
||||
catch(boost::bad_optional_access const&)
|
||||
{
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
BOOST_CHECK(false);
|
||||
}
|
||||
}
|
||||
|
||||
void test_function_value()
|
||||
{
|
||||
test_function_value_for<int>();
|
||||
test_function_value_for<double>();
|
||||
test_function_value_for<IntWrapper>();
|
||||
}
|
||||
|
||||
struct FatToIntConverter
|
||||
{
|
||||
static int conversions;
|
||||
int _val;
|
||||
FatToIntConverter(int val) : _val(val) {}
|
||||
operator int() const { conversions += 1; return _val; }
|
||||
};
|
||||
|
||||
int FatToIntConverter::conversions = 0;
|
||||
|
||||
void test_function_value_or()
|
||||
{
|
||||
test_function_value_or_for<int>();
|
||||
test_function_value_or_for<double>();
|
||||
test_function_value_or_for<IntWrapper>();
|
||||
|
||||
optional<int> oi(1);
|
||||
BOOST_CHECK(oi.value_or(FatToIntConverter(2)) == 1);
|
||||
BOOST_CHECK(FatToIntConverter::conversions == 0);
|
||||
|
||||
oi = boost::none;
|
||||
BOOST_CHECK(oi.value_or(FatToIntConverter(2)) == 2);
|
||||
BOOST_CHECK(FatToIntConverter::conversions == 1);
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_CXX11_REF_QUALIFIERS
|
||||
struct MoveOnly
|
||||
{
|
||||
explicit MoveOnly(int){}
|
||||
MoveOnly(MoveOnly &&){}
|
||||
void operator=(MoveOnly &&);
|
||||
private:
|
||||
MoveOnly(MoveOnly const&);
|
||||
void operator=(MoveOnly const&);
|
||||
};
|
||||
|
||||
optional<MoveOnly> makeMoveOnly()
|
||||
{
|
||||
return MoveOnly(1);
|
||||
}
|
||||
|
||||
// compile-time test
|
||||
void test_move_only_getters()
|
||||
{
|
||||
MoveOnly m1 = *makeMoveOnly();
|
||||
MoveOnly m2 = makeMoveOnly().value();
|
||||
MoveOnly m3 = makeMoveOnly().value_or(MoveOnly(1));
|
||||
unused_variable(m1);
|
||||
unused_variable(m2);
|
||||
unused_variable(m3);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int test_main( int, char* [] )
|
||||
{
|
||||
try
|
||||
{
|
||||
test_function_value();
|
||||
test_function_value_or();
|
||||
}
|
||||
catch ( ... )
|
||||
{
|
||||
BOOST_ERROR("Unexpected Exception caught!");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user