Compare commits

...

198 Commits

Author SHA1 Message Date
4c06d708d6 Merge branch 'develop' 2014-10-08 22:42:59 +02:00
35d5e25672 Removet compiler tests 2014-10-08 21:35:09 +02:00
a913650322 Doc typeo fixes + 1 test fix 2014-09-12 11:57:44 +02:00
55dc4c1dde Testing MSVC bugs 2014-09-05 16:28:02 +02:00
bda2001935 Testing MSVC bugs 2014-09-05 16:15:39 +02:00
eef3bfe079 Added a comaintainer to meta info 2014-09-04 23:47:46 +02:00
b7e8b1b54a Merge pull request #8 from danieljames/metadata
Create metadata file.
2014-09-04 23:44:52 +02:00
d4a4cdca1d Supply <string> to fix C++03 compile error on logic_error("...")
This change makes the library usable (again) on C++03 standard library
implementations where <stdexcept> doesn't imply inclusion of <string>,
e.g. STLport.
2014-08-28 02:45:14 +09:00
df01e9e429 Add metadata file. 2014-08-18 15:08:26 +01:00
953e7de70b Merge pull request #6 from boostorg/develop
rvalue ref overloads do not return by value
2014-07-17 10:15:50 +02:00
fea4882f24 rvalue ref overloads do not return by value 2014-07-10 13:49:36 +02:00
4115c41bf3 Merge branch 'develop' 2014-06-28 22:20:11 +02:00
18b8c4bb18 Catching up with N4078 2014-06-28 00:31:36 +02:00
fb578b02f2 Merge pull request #5 from boostorg/develop
Merge from develop
2014-06-24 10:38:15 +02:00
c7200c4aed Minor docs fixes (operator=) 2014-06-20 22:30:12 +02:00
599c75a6d3 various documentation fixes 2014-06-20 18:22:52 +02:00
4cbb67e505 Cleaner handling of explicit U to T conversions 2014-06-20 11:38:57 +02:00
4af83ecf83 Merge branch 'master' into develop 2014-06-18 18:13:40 +02:00
d70114b3dc Added func value_or_eval() 2014-06-18 16:42:48 +02:00
a158b85bd6 Merge branch 'develop' 2014-06-16 14:26:22 +02:00
9edf2ddac1 docs: fixed requirements in value_or() 2014-06-16 14:23:34 +02:00
0a2a8957fa bug fix: comma in BOOST_STATIC_ASSERT 2014-06-15 21:51:07 +02:00
31c9119266 value_or() requires that U is convertible to T
Due to Vladimir Batov.
2014-06-14 22:49:37 +02:00
8fc2901fad explicit operator bool becomes noexcept 2014-06-14 00:46:24 +02:00
04b9080612 Merge branch 'develop' 2014-06-09 16:19:11 +02:00
07bdbc3743 docs: optional<T> == nont_t requirements 2014-06-08 20:51:55 +02:00
befd3970d7 docs -- expanded tutprial section 2014-06-08 16:23:35 +02:00
d25b0cfd59 improved example in tutorial 2014-06-06 23:52:29 +02:00
a4e507077e More tests on emplace() 2014-06-06 23:40:45 +02:00
fdc98d17ca Added limited emplace() for older compilers 2014-06-06 23:24:43 +02:00
a448dc7554 Merge branch 'develop'
Conflicts:
	doc/html/index.html
2014-06-06 12:14:26 +02:00
dec71d338d Cleaned up docs 2014-06-06 00:53:15 +02:00
402f15e996 described relops in docs 2014-06-04 23:04:02 +02:00
3dd614fd91 Reorganized docs. Minor code fix wrt opt refs 2014-06-04 18:13:06 +02:00
f99618f09b Added ref-qualifiers to some accessors 2014-06-03 23:07:19 +02:00
2e583aaf30 Fixed code, updated docs, added emplace() 2014-06-03 17:36:18 +02:00
22baf1dd09 Fixed bug in test on compiler with no rvalue refs 2014-05-24 13:44:07 +02:00
3984c9f9a1 Added function value_or() 2014-05-23 16:38:42 +02:00
75271b73a8 Member fun value() that throws on uninitialized 2014-05-22 23:32:49 +02:00
5e59e10f93 Fix warnings with gcc 4.4 in C++11 mode
GCC 4.4 has support for an early draft of rvalue references. When compiling the conforming code it produces warnings such as '../boost/optional/optional.hpp:152: warning: returning reference to temporary'. In order to fix this regression use a special implementation of move(), similar to std::move() on this compiler.
2014-05-22 10:15:11 +04:00
24438efbf1 rebuilt documentation 2014-05-13 21:20:20 +02:00
3545f9b050 Merge branch 'develop' 2014-05-13 21:12:44 +02:00
e9f5ed41be binding to rvalues can be reenabled with a macro 2014-05-13 14:11:17 +02:00
1c9775a9d9 docs: described optional reference binding issues 2014-05-08 21:50:41 +02:00
f94846ccc5 Improved documentation. Added some noexcept. 2014-05-07 17:07:12 +02:00
6a790e0c97 Added a test that tests the compiler if references are bound correctly. Also added the second copyright notice. 2014-05-05 19:08:11 +02:00
86e759fb89 optional<const T&>::rval_reference_type is now T&& (not const T&) 2014-05-02 18:41:23 +02:00
897fdad11b Changed incorrect types in static assertions guarding against binding temporaries to optional refs 2014-05-02 15:41:43 +02:00
c51f3e810b The (in)equality comparison with boost::none does not require that T be EqualityComparable 2014-04-29 22:59:06 +02:00
d59f47156f Merge branch 'feature/move-semantics' into develop
Conflicts:
	doc/html/index.html
	include/boost/optional/optional.hpp
	test/Jamfile.v2
2014-04-29 01:24:10 +02:00
c9f1422560 Updated documentation; fixed optional::swap 2014-04-29 01:06:14 +02:00
01b22a0ff0 Added tests for move conversion between optional<T> and optional<U> 2014-04-28 16:51:49 +02:00
655a9e3035 Added README.md file 2014-04-28 16:01:55 +02:00
3816143646 Disabled assignment and construction from rvalue references in optional<const T&> 2014-04-28 15:48:55 +02:00
0e61751fab Added more tests for move operations, fixed bugs, disabled optional<T&&>. 2014-04-26 23:24:21 +02:00
c7cf80e5df Use BOOST_EXPLICIT_OPERATOR_BOOL for optional
I often have the problem that when I change a std::wstring to boost::optional<std::wstring> and the variable is used as a parameter with Boost.Format, the result silently changes from the string contents to "1".

This change prevents implicit conversion to bool if the compiler supports explicit conversion operators.
2014-04-26 15:26:37 +02:00
5c69bac12f Fixed unit tests (still need to add more unit tests for move semantics) 2014-04-26 00:22:39 +02:00
a26d11be87 Partially added move semantics (tests are still failing) 2014-04-22 22:36:19 +02:00
587ef8e988 Added 'raw' move semantics; no unit-tests 2014-04-14 23:44:34 +02:00
b4738ac07e Updated HTML documentation format using the super-project css and docbook-xsl-1.78.1 2014-04-12 20:54:37 +02:00
09f2c0f60e Merge branch 'use-super-project-css' of https://github.com/danieljames/optional into develop 2014-04-12 17:22:33 +02:00
a3b478b620 Use super-project's css file. 2014-04-12 09:10:24 +01:00
b7557909a3 Merge branch 'develop' 2014-04-12 00:02:38 +02:00
5981d984ed Merge branch 'master' of github.com:boostorg/optional 2014-04-11 23:43:13 +02:00
50d09367ca Rebuilt the HTML documentation using a newer xsltproc 2014-04-11 23:36:24 +02:00
40a1ec1ca2 Added HTML documentation generated from QuickBook sources (they were not in sync in the previous commit) 2014-04-11 23:30:49 +02:00
c5ca90ed58 Copy-editing optional documentation. Fixes #5382 and a few other issues I noticed while I was at it.
[SVN r71052]

Conflicts:
	doc/html/boost_optional/detailed_semantics.html
	doc/html/index.html
2014-04-11 12:40:07 +02:00
fdbac34bfb Fix some more typos and grammatical errors.
[SVN r71089]

Conflicts:
	doc/html/boost_optional/detailed_semantics.html
	doc/html/index.html
2014-04-11 11:47:09 +02:00
6cd1827fe2 Add link to header from synopsis. Fixes #4049. Add links to in place factory assignment operators.
[SVN r71092]

Conflicts:
	doc/html/index.html
2014-04-11 11:17:50 +02:00
c283c778e6 Correct definition of operator unspecified-bool-type. Make reference for is_initialized point to this operator. Fixes #6364.
[SVN r82911]
2014-04-11 11:12:39 +02:00
339a3c4ab8 Add assignment operators taking an InPlaceFactory to the Detailed Semantics section. Fixes #5378.
[SVN r71048]
2014-04-11 11:06:35 +02:00
c52654fa52 Try to fix VC8.
[SVN r83445]
2014-04-11 09:13:48 +02:00
e3226caccb Remove extra :'s. Fixes #7973.
[SVN r82909]
2014-04-11 00:32:48 +02:00
820cf7c815 Some doc typos. Fixes #7602.
[SVN r82910]
2014-04-11 00:30:54 +02:00
1895dbb984 Replace deprecated function reset in examples. Fixes #765.
[SVN r82912]
2014-04-11 00:27:36 +02:00
ed33f2bf2f Remove use of obsolete BOOST_NO_TEMPLATED_STREAMS macro.
It was only defined for no-longer-supported-gcc.

[SVN r86062]
2014-04-11 00:24:48 +02:00
51d3f2e761 Optional: Remove obsolete GCC version checks.
[SVN r86068]
2014-04-11 00:14:35 +02:00
60f3efc852 Add a forward declaration of the ostream operator for optional. Fixes #2103.
[SVN r82930]
2014-04-10 23:54:52 +02:00
8d6f6ddf4f Work around msvc bug when explicitly destroying a class with a virtual base. Fixes #5940.
[SVN r82915]
2014-04-10 23:51:56 +02:00
84deab1aba Optional: Remove obsolete MSVC version checks.
[SVN r86019]
2014-04-10 23:47:30 +02:00
a43db097ca Use __may_alias__ instead of may_alias. Fixes #6410.
[SVN r82919]
2014-04-10 23:33:36 +02:00
b4bb05a771 Create merge base for git. 2014-04-06 14:18:57 +01:00
3cf0363668 Optional: Remove obsolete GCC version checks.
[SVN r86068]
2013-09-30 15:58:48 +00:00
c9ead30713 Remove use of obsolete BOOST_NO_TEMPLATED_STREAMS macro.
It was only defined for no-longer-supported-gcc.

[SVN r86062]
2013-09-30 15:56:52 +00:00
931cf3941b Optional: Remove obsolete MSVC version checks.
[SVN r86019]
2013-09-30 00:17:11 +00:00
16657e5e1d Try to fix VC8.
[SVN r83445]
2013-03-15 18:24:41 +00:00
cb09282472 Update optional documentation.
[SVN r82931]
2013-02-16 19:42:42 +00:00
655eb739fa Add a forward declaration of the ostream operator for optional. Fixes #2103.
[SVN r82930]
2013-02-16 19:32:20 +00:00
e8853f23cd Use __may_alias__ instead of may_alias. Fixes #6410.
[SVN r82919]
2013-02-16 02:48:46 +00:00
ff48f2b3a0 Work around msvc bug when explicitly destroying a class with a virtual base. Fixes #5940.
[SVN r82915]
2013-02-15 19:22:34 +00:00
e40c2654d9 Replace deprecated function reset in examples. Fixes #765.
[SVN r82912]
2013-02-15 18:50:29 +00:00
ab0ffa1c01 Correct definition of operator unspecified-bool-type. Make reference for is_initialized point to this operator. Fixes #6364.
[SVN r82911]
2013-02-15 18:44:59 +00:00
a5c2ab2125 Some doc typos. Fixes #7602.
[SVN r82910]
2013-02-15 18:28:38 +00:00
181e56a70a Remove extra :'s. Fixes #7973.
[SVN r82909]
2013-02-15 18:21:04 +00:00
9bd310086a Optional: merge 81031
[SVN r81036]
2012-10-21 12:01:37 +00:00
f6db3d6bc3 Optional: fix some unused parameter warnings
[SVN r81031]
2012-10-21 06:30:04 +00:00
f921762bf6 Add link to header from synopsis. Fixes #4049. Add links to in place factory assignment operators.
[SVN r71092]
2011-04-07 21:05:15 +00:00
f9c46f9a86 Fix some more typos and grammatical errors.
[SVN r71089]
2011-04-07 19:56:55 +00:00
c1d2381a9b Copy-editing optional documentation. Fixes #5382 and a few other issues I noticed while I was at it.
[SVN r71052]
2011-04-06 21:56:23 +00:00
960631e201 Add assignment operators taking an InPlaceFactory to the Detailed Semantics section. Fixes #5378.
[SVN r71048]
2011-04-06 20:54:18 +00:00
6ed68269a8 Merge [44825] and [45264] from the trunk.
[SVN r70796]
2011-03-31 19:47:42 +00:00
9275e2b8aa Merge [53671] from the trunk.
[SVN r70790]
2011-03-31 16:47:48 +00:00
545f8933bc Merged changes from trunk: add namespace scope swap forward declaration to fix member swap copmilation. Swap implementation now uses Boost.Utility.Swap. Fixes #4987.
[SVN r67307]
2010-12-18 21:29:39 +00:00
e9989b260e Refs #4987. Added forward declaration of namespace-scope swap for boost::optional, this should fix GCC compilation errors. Also swap implementation now uses Boost.Utility.Swap to make use of the workarounds for some broken compilers. If it breaks for your compiler, let me know in the mentioned ticket.
[SVN r67288]
2010-12-17 21:12:56 +00:00
646488e0e2 operator>> behavior changed slightly so that the stream is not accessed when unrecognized character sequence is detected.
[SVN r67184]
2010-12-12 11:35:19 +00:00
ef2d285d47 Merged changes from trunk. Fixes #3395. Also updates swap behavior: if default constructor has no-throw guarantee, swap will use it to provide no-throw guarantee itself. operator>> behavior changed slightly so that the stream is not accessed when unrecognized character sequence is detected. The stream is marked with failbit in such a case.
[SVN r67183]
2010-12-12 11:34:12 +00:00
64d8062621 The may_alias workaround is also disabled for GCC prior to 3.2. Also added description for this workaround.
[SVN r67112]
2010-12-08 18:32:36 +00:00
d39627c5b6 boost/optional/optional.hpp: avoid gcc 3.2 warnings
[SVN r67109]
2010-12-08 17:53:29 +00:00
f88c8ae423 Refs #3395. Optional construction and assignment now works correctly for types with overridden operator&. Also silenced some GCC warnings about broken strict aliasing rules.
[SVN r67020]
2010-12-05 14:43:18 +00:00
ab01dfff7e Fully qualify ios flags. Fixes compilation of PropertyTree, bug 4459.
[SVN r64342]
2010-07-25 22:21:45 +00:00
8608ad1497 Fixed behaviour in case of invalid input
[SVN r64208]
2010-07-20 19:21:44 +00:00
c93e5a88c7 Fixed extraction operator for empty optionals
[SVN r64206]
2010-07-20 18:20:40 +00:00
425d141cbf Test for fixed extraction operator for empty optinals
[SVN r64205]
2010-07-20 18:20:01 +00:00
3d859e5fbe Merge documentation changes.
[SVN r64186]
2010-07-19 23:29:09 +00:00
57c07c7a57 Fix doc build for 2 libraries which use own css.
I changed the default to use doc/src/boostbook.css. So add an explicit
location to libraries which use their own stylesheet.

[SVN r64170]
2010-07-19 20:17:58 +00:00
55f54b5921 Merge some link fixes.
[64006] and [64059].


[SVN r64061]
2010-07-15 21:19:14 +00:00
97e314f03a Fix some header links.
[SVN r64006]
2010-07-14 08:15:33 +00:00
ed450cbf68 Spirit: merging from trunk upto rev. 63622
[SVN r63642]
2010-07-05 03:11:56 +00:00
46f4308166 Merge documentation fixes.
* Use `doc/src/*.css` instead of `doc/html/*.css`.
* Remove wiki and people directories.
* Some documentation fixes.
* Left out `minimal.css` changes and boostbook changes because of clashes.


[SVN r63347]
2010-06-26 12:30:09 +00:00
bccd75c72f Update various libraries' documentation build.
Mostly to use the images and css files under doc/src instead of
doc/html, usually be deleting the settings in order to use the defaults.
Also add 'boost.root' to some builds in order to fix links which rely on
it.

[SVN r63146]
2010-06-20 18:00:48 +00:00
16f0a0aaaf Expose the "types" typedef of boost::optional_detail::operator_base as
public, rather than protected, since Spirit pokes at this typedef. 


[SVN r61832]
2010-05-06 21:44:18 +00:00
93f84f3351 Merge [57812] rebuild optional documentation.
[SVN r57813]
2009-11-20 10:30:17 +00:00
a63dbe0f14 Rebuild optional docs.
[SVN r57812]
2009-11-20 10:26:23 +00:00
066dd6f345 rm cmake from trunk. I'm not entirely sure this is necessary to satisfy the inspect script, but I'm not taking any chances, and it is easy to put back
[SVN r56942]
2009-10-17 02:07:38 +00:00
04c1b67629 rm cmake from the release branch before it goes out broken. Policy dictates that you never commit to release, you commit to trunk and merge to release.
[SVN r56941]
2009-10-17 01:10:45 +00:00
4e628ed4a6 Copyrights on CMakeLists.txt to keep them from clogging up the inspect
reports.  This is essentially the same commit as r55095 on the release
branch.



[SVN r55159]
2009-07-26 00:49:56 +00:00
a81ac6e5aa Add basic copyright/license to keep cmake out of the inspection report
[SVN r55095]
2009-07-22 21:51:01 +00:00
8682f2bbaa avoid C style casts
[SVN r53671]
2009-06-06 09:42:41 +00:00
fac0a7d65d Fixed almost all tab and min/max issues found by inspect tool
[SVN r53142]
2009-05-20 19:41:20 +00:00
fea89e84f3 Fixed most tab and min/max issues from trunk inspection report
[SVN r53141]
2009-05-20 19:19:00 +00:00
30419ed5e0 Add support for "known failures", which match the build name via a
regular expression and are attached to test cases as a "known-failure"
label.


[SVN r53014]
2009-05-15 04:44:20 +00:00
2772bfc08d optional docs in cmakeland
[SVN r52251]
2009-04-08 12:09:58 +00:00
41a677bdaf Merge PDF build changes from Trunk.
[SVN r51417]
2009-02-23 18:39:32 +00:00
361943e033 Add PDF generation options to fix external links to point to the web site.
Added a few more Boostbook based libs that were missed first time around.
Fixed PDF naming issues.

[SVN r51284]
2009-02-17 10:05:58 +00:00
20c9fc8ebe Fix the optional and numeric/conversion docs so they generate valid Docbook XML that can be transformed into PDF's.
Regenerated HTML versions of the docs.

[SVN r51218]
2009-02-12 14:01:48 +00:00
313d15c56c Merge several documentation fixes. Plus a small inspect fix.
Merged revisions 50798-50799,50837-50839,50847-50848 via svnmerge from 
https://svn.boost.org/svn/boost/trunk

........
  r50798 | danieljames | 2009-01-26 23:14:53 +0000 (Mon, 26 Jan 2009) | 5 lines
  
  Make checking for duplicated names case insensitive.
  
  This avoids generating filenames with names that only differ by case as they
  cause problems on case insensitive file systems.
........
  r50799 | danieljames | 2009-01-26 23:29:52 +0000 (Mon, 26 Jan 2009) | 1 line
  
  Label the line ending inspect errors.
........
  r50837 | danieljames | 2009-01-28 09:14:21 +0000 (Wed, 28 Jan 2009) | 1 line
  
  Add scope exit to the root html file.
........
  r50838 | danieljames | 2009-01-28 09:14:45 +0000 (Wed, 28 Jan 2009) | 1 line
  
  Fix a link in the typeof forwarding html file.
........
  r50839 | danieljames | 2009-01-28 09:14:56 +0000 (Wed, 28 Jan 2009) | 1 line
  
  Fix an incorrectly escaped right arrow.
........
  r50847 | danieljames | 2009-01-28 15:17:34 +0000 (Wed, 28 Jan 2009) | 2 lines
  
  Fix some documentation issues with scope_exit.
........
  r50848 | danieljames | 2009-01-28 15:32:46 +0000 (Wed, 28 Jan 2009) | 1 line
  
  Generate the scope_exit documentation.
........


[SVN r50849]
2009-01-28 15:53:42 +00:00
fd38be1636 Fix an incorrectly escaped right arrow.
[SVN r50839]
2009-01-28 09:14:56 +00:00
6b8df2a27d merge of cmake build files from trunk per beman
[SVN r50756]
2009-01-24 18:57:20 +00:00
9f655c6932 Updating dependency information for modularized libraries.
[SVN r49628]
2008-11-07 17:05:27 +00:00
e7d7b014d2 Updating CMake files to latest trunk. Added dependency information for regression tests and a few new macros for internal use.
[SVN r49627]
2008-11-07 17:02:56 +00:00
2af3ec341b Continuing merge of CMake build system files into trunk with the encouragement of Doug Gregor
[SVN r49510]
2008-11-01 13:15:41 +00:00
e68e68276c Rebuild the numeric/conversion and optional documentation. Which should fix a few links.
[SVN r49259]
2008-10-10 21:35:16 +00:00
101bb76c18 Add minor documentation fixes to the release branch.
(I left out the changes to the hash library).

Merged via svnmerge from 
https://svn.boost.org/svn/boost/trunk

................
  r44807 | danieljames | 2008-04-27 08:39:49 +0100 (Sun, 27 Apr 2008) | 78 lines
  
  Merge in documentation fixes.  Apart from the change to optional's documenation
  Jamfile, which I included by mistake.
  
  I wrote about this at:
  
  http://lists.boost.org/Archives/boost/2008/04/136405.php
  
  Merged revisions 44585-44806 via svnmerge from 
  https://svn.boost.org/svn/boost/branches/doc
  
  ........
    r44585 | danieljames | 2008-04-19 16:25:27 +0100 (Sat, 19 Apr 2008) | 2 lines
    
    Fix broken link to vacpp in bjam docs.
  ........
    r44586 | danieljames | 2008-04-19 16:27:36 +0100 (Sat, 19 Apr 2008) | 2 lines
    
    Fix broken link to bcpp in bjam docs.
  ........
    r44587 | danieljames | 2008-04-19 16:33:58 +0100 (Sat, 19 Apr 2008) | 2 lines
    
    DateTime documentation - Fix a link to the serialization library.
  ........
    r44588 | danieljames | 2008-04-19 16:35:36 +0100 (Sat, 19 Apr 2008) | 2 lines
    
    Fix some links in interprocess & intrusive.
  ........
    r44589 | danieljames | 2008-04-19 16:37:39 +0100 (Sat, 19 Apr 2008) | 2 lines
    
    Fix some links in the python docs.
  ........
    r44590 | danieljames | 2008-04-19 16:38:29 +0100 (Sat, 19 Apr 2008) | 2 lines
    
    Work around a quickbook bug which is affecting the python docs.
  ........
    r44591 | danieljames | 2008-04-19 16:39:34 +0100 (Sat, 19 Apr 2008) | 2 lines
    
    Fix a broken link in the numeric conversion docs.
  ........
    r44592 | danieljames | 2008-04-19 16:40:45 +0100 (Sat, 19 Apr 2008) | 2 lines
    
    Fix some links in the optional docs.
  ........
    r44593 | danieljames | 2008-04-19 16:42:09 +0100 (Sat, 19 Apr 2008) | 2 lines
    
    Fix link to the hash documentation from bimap.
  ........
    r44599 | danieljames | 2008-04-19 18:07:33 +0100 (Sat, 19 Apr 2008) | 2 lines
    
    Fix a typo in the format library.
  ........
    r44600 | danieljames | 2008-04-19 19:20:59 +0100 (Sat, 19 Apr 2008) | 1 line
    
    Initialise svnmerge.
  ........
    r44641 | danieljames | 2008-04-20 18:59:47 +0100 (Sun, 20 Apr 2008) | 2 lines
    
    Fix the lincense url in shared container iterator documentation.
  ........
    r44642 | danieljames | 2008-04-20 19:00:00 +0100 (Sun, 20 Apr 2008) | 2 lines
    
    Fix image link in the mpi documentation.
  ........
    r44643 | danieljames | 2008-04-20 19:00:11 +0100 (Sun, 20 Apr 2008) | 2 lines
    
    Fix a typo in the spirit docs.
  ........
    r44644 | danieljames | 2008-04-20 19:00:23 +0100 (Sun, 20 Apr 2008) | 2 lines
    
    Escape the slash so that quickbook doesn't think it the start of an italic section, and mess up the link. Refs #1844
  ........
    r44647 | danieljames | 2008-04-20 19:39:47 +0100 (Sun, 20 Apr 2008) | 2 lines
    
    Fix another typo in spirit docs.
  ........
................
  r45232 | danieljames | 2008-05-08 22:50:19 +0100 (Thu, 08 May 2008) | 1 line
  
  Fix some invalid xml by replacing ampersands with character entities.
................
  r45576 | danieljames | 2008-05-20 16:39:25 +0100 (Tue, 20 May 2008) | 20 lines
  
  Merge some small documentation fixes from the doc branch, and mark some
  previously merged changes as merged.
  
  Merged revisions 44811,45129,45142,45154,45281-45282,45365 via svnmerge from 
  https://svn.boost.org/svn/boost/branches/doc
  
  ........
    r45129 | danieljames | 2008-05-05 12:36:50 +0100 (Mon, 05 May 2008) | 2 lines
    
    Update navbar links in boostbook.
  ........
    r45282 | danieljames | 2008-05-11 14:15:31 +0100 (Sun, 11 May 2008) | 2 lines
    
    Group functions in the hash header - requires Frank's free-function-group fix.
    (not included in release branch).
  ........
    r45365 | danieljames | 2008-05-14 21:39:00 +0100 (Wed, 14 May 2008) | 2 lines
    
    Add boost.root to standalone hash documentation.
    (not included in release branch).
  ........
................


[SVN r45622]
2008-05-21 20:57:05 +00:00
3ebabcb2d8 Fixed syntax of optional_swap_should_use_default_constructor and swap template specializations that I added 2 days ago (changeset [45265]). Was accepted by MSVC, but rejected by other compilers.
[SVN r45295]
2008-05-12 13:29:52 +00:00
63f6e7f45e Added more optional::swap tests, especially on self swap, on specializing boost::swap for optional<T>, and on swapping optional<T> when T is a template class.
[SVN r45265]
2008-05-10 14:53:51 +00:00
43eac5bb12 Added forward declaration of boost::optional_swap_should_use_default_constructor.
[SVN r45264]
2008-05-10 14:42:49 +00:00
74674531c8 Replaced "using std::swap" by "using boost::swap" within optional::swap member function, hoping to fix GCC test failures, as mentioned at http://article.gmane.org/gmane.comp.lib.boost.devel/174350 "Re: [optional] problems with swap()"
[SVN r44826]
2008-04-27 21:09:50 +00:00
a4572497be Added forward declaration of optional<T>'s boost::swap overload, as mentioned at http://article.gmane.org/gmane.comp.lib.boost.devel/174350 "Re: [optional] problems with swap()"
[SVN r44825]
2008-04-27 21:07:10 +00:00
951b49f992 Merge in documentation fixes. Apart from the change to optional's documenation
Jamfile, which I included by mistake.

Fixes #1659, #1661, #1684, #1685, 1687, #1690, #1801

I wrote about this at:

http://lists.boost.org/Archives/boost/2008/04/136405.php

Merged revisions 44585-44806 via svnmerge from 
https://svn.boost.org/svn/boost/branches/doc

........
  r44585 | danieljames | 2008-04-19 16:25:27 +0100 (Sat, 19 Apr 2008) | 2 lines
  
  Fix broken link to vacpp in bjam docs. Refs #1512
........
  r44586 | danieljames | 2008-04-19 16:27:36 +0100 (Sat, 19 Apr 2008) | 2 lines
  
  Fix broken link to bcpp in bjam docs. Refs #1513
........
  r44587 | danieljames | 2008-04-19 16:33:58 +0100 (Sat, 19 Apr 2008) | 2 lines
  
  DateTime documentation - Fix a link to the serialization library. Refs #1659
........
  r44588 | danieljames | 2008-04-19 16:35:36 +0100 (Sat, 19 Apr 2008) | 2 lines
  
  Fix some links in interprocess & intrusive. Refs #1661
........
  r44589 | danieljames | 2008-04-19 16:37:39 +0100 (Sat, 19 Apr 2008) | 2 lines
  
  Fix some links in the python docs. Refs #1684.
........
  r44590 | danieljames | 2008-04-19 16:38:29 +0100 (Sat, 19 Apr 2008) | 2 lines
  
  Work around a quickbook bug which is affecting the python docs. Refs #1684.
........
  r44591 | danieljames | 2008-04-19 16:39:34 +0100 (Sat, 19 Apr 2008) | 2 lines
  
  Fix a broken link in the numeric conversion docs. Refs #1685
........
  r44592 | danieljames | 2008-04-19 16:40:45 +0100 (Sat, 19 Apr 2008) | 2 lines
  
  Fix some links in the optional docs. Refs #1687
........
  r44593 | danieljames | 2008-04-19 16:42:09 +0100 (Sat, 19 Apr 2008) | 2 lines
  
  Fix link to the hash documentation from bimap. Refs #1690
........
  r44599 | danieljames | 2008-04-19 18:07:33 +0100 (Sat, 19 Apr 2008) | 2 lines
  
  Fix a typo in the format library. Refs #1801
........
  r44600 | danieljames | 2008-04-19 19:20:59 +0100 (Sat, 19 Apr 2008) | 1 line
  
  Initialise svnmerge.
........
  r44641 | danieljames | 2008-04-20 18:59:47 +0100 (Sun, 20 Apr 2008) | 2 lines
  
  Fix the lincense url in shared container iterator documentation.
........
  r44642 | danieljames | 2008-04-20 19:00:00 +0100 (Sun, 20 Apr 2008) | 2 lines
  
  Fix image link in the mpi documentation.
........
  r44643 | danieljames | 2008-04-20 19:00:11 +0100 (Sun, 20 Apr 2008) | 2 lines
  
  Fix a typo in the spirit docs.
........
  r44644 | danieljames | 2008-04-20 19:00:23 +0100 (Sun, 20 Apr 2008) | 2 lines
  
  Escape the slash so that quickbook doesn't think it the start of an italic section, and mess up the link. Refs #1844
........
  r44647 | danieljames | 2008-04-20 19:39:47 +0100 (Sun, 20 Apr 2008) | 2 lines
  
  Fix another typo in spirit docs.
........


[SVN r44807]
2008-04-27 07:39:49 +00:00
1afed544db Added unit tests, testing optional<T> swap improvements of revision [44766]
[SVN r44767]
2008-04-25 16:52:34 +00:00
66c366d18a Improved swap for optional<T>, co-written by Thorsten and Fernando: added support for tweaking whether swap should use T's default constructor. Added swap member function. Discussed at Boost developers' mailing list, "[optional] problems with swap()", http://lists.boost.org/Archives/boost/2008/04/135882.php
[SVN r44766]
2008-04-25 16:50:32 +00:00
5a1938ccf7 Rebuild a lot of documentation.
[SVN r43650]
2008-03-16 11:38:32 +00:00
4c11dcc703 optional docs new version
[SVN r43257]
2008-02-14 19:35:00 +00:00
472a68c920 redirect optional docs to new version
[SVN r43248]
2008-02-14 17:44:21 +00:00
3e33d4a200 optional docs fixes
[SVN r43247]
2008-02-14 17:43:52 +00:00
95c864e119 Cast to base added to avoid a call to the convertir constructor/assignment (see Tickes 1419 and 1420)
[SVN r41381]
2007-11-25 20:26:14 +00:00
eb19cc2729 Full merge from trunk at revision 41356 of entire boost-root tree.
[SVN r41370]
2007-11-25 18:38:02 +00:00
5956702c32 Full merge from trunk at revision 41356 of entire boost-root tree.
[SVN r41369]
2007-11-25 18:07:19 +00:00
9afdbe65e7 // Add or correct comment identifying Boost library this header is associated with.
[SVN r41173]
2007-11-17 20:13:16 +00:00
f6518df0c4 Get rid of .cvsignore files
[SVN r41107]
2007-11-15 15:20:27 +00:00
05a685b035 Fixed intention in the added binding test
[SVN r40860]
2007-11-06 22:21:43 +00:00
3b5b5d82a0 Added test to ensure proper binding of optional references (in reference to Ticket 1301)
[SVN r40707]
2007-11-02 23:41:37 +00:00
06ba35cd42 Fixed error reported by Edward Diener
[SVN r40706]
2007-11-02 23:06:42 +00:00
3499d477dc Merged changests from RC_1_34_0 - base rev 33417
[SVN r40705]
2007-11-02 22:56:23 +00:00
a690c8e7a2 Merged changests from RC_1_34_0 - base rev 33417
[SVN r40704]
2007-11-02 22:55:49 +00:00
4ba562871e Starting point for releases
[SVN r39706]
2007-10-05 14:25:06 +00:00
c8e54ef488 Remove V1 Jamfiles
[SVN r38516]
2007-08-08 19:02:26 +00:00
3ff4258fbb This commit was manufactured by cvs2svn to create tag
'Version_1_34_1'.

[SVN r38286]
2007-07-24 19:28:14 +00:00
07ce2fc860 new quickbook docs for optional
[SVN r37809]
2007-05-29 06:40:25 +00:00
35040aab6a Add missing newline at eof.
[SVN r37425]
2007-04-12 19:43:30 +00:00
bfd5cc0a87 Updated single-header implementation
[SVN r37420]
2007-04-12 14:25:21 +00:00
0fd45d73b1 Doc update to reflect latest additions
[SVN r37368]
2007-04-05 18:55:22 +00:00
3bf8d0f1b4 Fixed incorrect BORLANDC macro
[SVN r37314]
2007-03-28 21:26:19 +00:00
789cb2b24f boost::none implementation fixed for bcc <= 5.6.4
[SVN r37301]
2007-03-27 16:02:57 +00:00
7287f2bf11 in_palce_factory.apply problem fixed
[SVN r37157]
2007-03-07 20:17:23 +00:00
b6a1946a60 none_t/none reimplemented to avoid precompiled header issues (thanks to Joe Gottam)
optional<T> now has direct relational operator
optional<T>::operator-> fixed for reference types


[SVN r37126]
2007-03-01 23:08:33 +00:00
9bbde2be14 Fixed operator->() for optional references.
[SVN r37125]
2007-03-01 21:50:12 +00:00
f258713788 Fixed operator->() for optional references.
[SVN r37124]
2007-03-01 21:39:25 +00:00
3dc3f46d66 Merged copyright and license addition
[SVN r35907]
2006-11-07 19:27:00 +00:00
be7249b537 Add copyright, license
[SVN r35905]
2006-11-07 19:11:57 +00:00
c23c21d9c2 Remove obsolete Boost.Build v1 files.
[SVN r35880]
2006-11-06 17:10:46 +00:00
1b7002f663 misused "precedence" changed to "precedent"
[SVN r35831]
2006-11-04 02:13:53 +00:00
5182283649 misused "precedence" changed to "precedent"
[SVN r35831]
2006-11-04 02:13:53 +00:00
4599ae0bfd merge from head [removed unnamed namespace (see http://lists.boost.org/Archives/boost/2006/07/107873.php); usual copyright/license/url fixes]
[SVN r34647]
2006-07-20 23:23:09 +00:00
16a8ccbecc removed unnamed namespace (see http://lists.boost.org/Archives/boost/2006/07/107873.php); usual copyright/license/url fixes
[SVN r34646]
2006-07-20 23:17:22 +00:00
734e5b5283 Some additional functions added to optional (being new there won't be regressions)
[SVN r34411]
2006-06-26 18:01:38 +00:00
9ccefc8349 workaround for Borland
[SVN r34288]
2006-06-12 19:02:41 +00:00
a77dff3e11 workaround for Borland
[SVN r34288]
2006-06-12 19:02:41 +00:00
9516a779fe Disambiguated certain constructs.
[SVN r34227]
2006-06-08 01:47:33 +00:00
0961a6598a Disambiguated certain constructs.
[SVN r34226]
2006-06-08 01:39:40 +00:00
03248b5fd8 This commit was manufactured by cvs2svn to create branch 'RC_1_34_0'.
[SVN r33417]
2006-03-21 02:26:31 +00:00
c7e74ce372 Fixed bug in optional_io
[SVN r32979]
2006-02-17 21:15:58 +00:00
91bdde095d Non-templated iostreams fix in optional_io
Better "illegal conversion" fail test


[SVN r32972]
2006-02-16 20:52:55 +00:00
0e10374194 AlisdairM BCB2006 patch reapplied to HEAD
[SVN r32820]
2006-02-10 20:52:25 +00:00
d3f9e112c4 Update Jamfile.v2
[SVN r32761]
2006-02-09 09:50:56 +00:00
864adf2e87 Now commited in HEAD
[SVN r32748]
2006-02-08 19:29:54 +00:00
0be943c2f6 Added simple operators << and >> to optional<>
[SVN r32533]
2006-02-03 21:39:21 +00:00
04bec76068 Fixed the converting assignment bug in optional<>
Fixed the usage of 'None' in converter.h, which is declared as a macro in X11/X.h


[SVN r32531]
2006-02-03 19:56:03 +00:00
93 changed files with 15553 additions and 1874 deletions

15
README.md Normal file
View File

@ -0,0 +1,15 @@
optional
========
A library for representing optional (nullable) objects in C++.
```cpp
optional<int> readInt(); // this function may return either an int or a not-an-int
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";
```
For more information refer to the documentation provided with this library.

95
doc/00_optional.qbk Normal file
View File

@ -0,0 +1,95 @@
[library Boost.Optional
[quickbook 1.4]
[authors [Cacciola Carballal, Fernando Luis]]
[copyright 2003-2007 Fernando Luis Cacciola Carballal]
[copyright 2014 Andrzej Krzemie&#324;ski]
[category miscellaneous]
[id optional]
[dirname optional]
[purpose
Discriminated-union wrapper for optional values
]
[source-mode c++]
[license
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
[@http://www.boost.org/LICENSE_1_0.txt])
]
]
[/ Macros will be used for links so we have a central place to change them ]
[/ Cited Boost resources ]
[def __BOOST_VARIANT__ [@../../../variant/index.html Boost.Variant]]
[def __BOOST_TUPLE__ [@../../../tuple/index.html Boost.Tuple]]
[def __BOOST_TRIBOOL__ [@../../../../doc/html/tribool.html boost::tribool]]
[def __OPTIONAL_POINTEE__ [@../../../utility/OptionalPointee.html `OptionalPointee`]]
[def __COPY_CONSTRUCTIBLE__ [@../../../utility/CopyConstructible.html `CopyConstructible`]]
[def __MOVE_CONSTRUCTIBLE__ `MoveConstructible`]
[def __FUNCTION_EQUAL_POINTEES__ [@../../../utility/OptionalPointee.html#equal `equal_pointees()`]]
[def __FUNCTION_LESS_POINTEES__ [@../../../utility/OptionalPointee.html#less `less_pointees()`]]
[def __IN_PLACE_FACTORY_HPP__ [@../../../../boost/utility/in_place_factory.hpp in_place_factory.hpp]]
[def __TYPED_IN_PLACE_FACTORY_HPP__ [@../../../../boost/utility/typed_in_place_factory.hpp typed_in_place_factory.hpp]]
[/ Other web resources ]
[def __HASKELL__ [@http://www.haskell.org/ Haskell]]
[def __SGI_DEFAULT_CONSTRUCTIBLE__ [@http://www.sgi.com/tech/stl/DefaultConstructible.html `DefaultConstructible`]]
[def __SGI_LESS_THAN_COMPARABLE__ [@http://www.sgi.com/tech/stl/LessThanComparable.html `LessThanComparable`]]
[def __SGI_EQUALITY_COMPARABLE__ [@http://www.sgi.com/tech/stl/EqualityComparable.html `EqualityComparable`]]
[def __SGI_GENERATOR__ [@http://www.sgi.com/tech/stl/Generator.html `Generator`]]
[/ Icons ]
[def __SPACE__ [$images/space.png]]
[def __GO_TO__ [$images/callouts/R.png]]
[section Introduction]
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.
[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 differently. 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.
[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 01_quick_start.qbk]
[section Tutorial]
[include 10_motivation.qbk]
[include 11_development.qbk]
[include 12_when_to_use.qbk]
[include 13_relational_operators.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]

158
doc/01_quick_start.qbk Normal file
View File

@ -0,0 +1,158 @@
[/
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 a `std::string` to an `int`. It is possible that for a given string (e.g. `"cat"`) there exists 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::optional<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::optional<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::optional<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`. Finally, you can provide a callback to be called when trying to access the contained value fails:
int fallback_to_default()
{
cerr << "could not convert; using -1 instead" << endl;
return -1;
}
int l = convert(text).value_or_eval(fallback_to_default);
This will call the provided callback and return whatever the callback returns. The callback can have side effects: they will only be observed when the optional object does not contain a value.
Now, let's consider how function `convert` can be implemented.
boost::optional<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::optional<int> convert(const std::string& text)
{
boost::optional<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 'mixed' 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 the contained value using `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
{
mutable boost::optional<const Resource> resource_;
public:
Widget() {}
const Resource& getResource() const // 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 __SGI_LESS_THAN_COMPARABLE__ whenever `T` is __SGI_LESS_THAN_COMPARABLE__. 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`.
[endsect]
[endsect]

80
doc/10_motivation.qbk Normal file
View File

@ -0,0 +1,80 @@
[/
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 Motivation]
Consider these functions which should return a value but which might not have
a value to return:
* (A) `double sqrt(double n );`
* (B) `char get_async_input();`
* (C) `point polygon::get_any_point_effectively_inside();`
There are different approaches to the issue of not having a value to return.
A typical approach is to consider the existence of a valid return value as a
postcondition, so that if the function cannot compute the value to return, it
has either undefined behavior (and can use 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.
However, function (B), because of its asynchronous nature, does not fail just
because it can't find a value to return; so it is incorrect to consider such
a situation an error and assert or throw an exception. This function must
return, and somehow, must tell the callee that it is not returning a meaningful
value.
A similar situation occurs with function (C): it is conceptually an error to
ask a ['null-area] polygon to return a point inside itself, but in many
applications, it is just impractical for performance reasons to treat this as
an error (because detecting that the polygon has no area might be too expensive
to be required to be tested previously), and either an arbitrary point
(typically at infinity) is returned, or some efficient way to tell the callee
that there is no such point is used.
There are various mechanisms to let functions communicate that the returned
value is not valid. One such mechanism, which is quite common since it has
zero or negligible overhead, is to use a special value which is reserved to
communicate this. Classical examples of such special values are `EOF`,
`string::npos`, points at infinity, etc...
When those values exist, i.e. the return type can hold all meaningful values
['plus] the ['signal] value, this mechanism is quite appropriate and well known.
Unfortunately, there are cases when such values do not exist. In these cases,
the usual alternative is either to use a wider type, such as `int` in place of
`char`; or a compound type, such as `std::pair<point,bool>`.
Returning a `std::pair<T,bool>`, thus attaching a boolean flag to the result
which indicates if the result is meaningful, has the advantage that can be
turned into a consistent idiom since the first element of the pair can be
whatever the function would conceptually return. For example, the last two
functions could have the following interface:
std::pair<char,bool> get_async_input();
std::pair<point,bool> polygon::get_any_point_effectively_inside();
These functions use a consistent interface for dealing with possibly nonexistent
results:
std::pair<point,bool> p = poly.get_any_point_effectively_inside();
if ( p.second )
flood_fill(p.first);
However, not only is this quite a burden syntactically, it is also error prone
since the user can easily use the function result (first element of the pair)
without ever checking if it has a valid value.
Clearly, we need a better idiom.
[endsect]

251
doc/11_development.qbk Normal file
View File

@ -0,0 +1,251 @@
[/
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 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]. (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]
(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
is, when a variable is declared as `optional<T>` and no initial value is given,
the variable is ['formally] uninitialized. A formally uninitialized optional object
has conceptually no value at all and this situation can be tested at runtime. It
is formally ['undefined behavior] to try to access the value of an uninitialized
optional. An uninitialized optional can be assigned a value, in which case its initialization state changes to initialized. Furthermore, given the formal
treatment of initialization states in optional objects, it is even possible to
reset an optional to ['uninitialized].
In C++ there is no formal notion of uninitialized objects, which means that
objects always have an initial value even if indeterminate.
As discussed on the previous section, this has a drawback because you need
additional information to tell if an object has been effectively initialized.
One of the typical ways in which this has been historically dealt with is via
a special value: `EOF`, `npos`, -1, etc... This is equivalent to adding the
special value to the set of possible values of a given type. This super set of
`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`.
Using the __BOOST_VARIANT__ library, this model can be implemented in terms of `boost::variant<T,nil_t>`.
There is precedent for a discriminated union as a model for an optional value:
the __HASKELL__ [*Maybe] built-in type constructor. Thus, a discriminated union
`T+nil_t` serves as a conceptual foundation.
A `variant<T,nil_t>` follows naturally from the traditional idiom of extending
the range of possible values adding an additional sentinel value with the
special meaning of ['Nothing]. However, this additional ['Nothing] value is largely
irrelevant for our purpose since our goal is to formalize the notion of
uninitialized objects and, while a special extended value can be used to convey
that meaning, it is not strictly necessary in order to do so.
The observation made in the last paragraph about the irrelevant nature of the
additional `nil_t` with respect to [_purpose] of `optional<T>` suggests an
alternative model: a ['container] that either has a value of `T` or nothing.
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.
In any event, both the discriminated-union or the single-element container
models serve as a conceptual ground for a class representing optional—i.e.
possibly uninitialized—objects.
For instance, these models show the ['exact] semantics required for a wrapper
of optional values:
Discriminated-union:
* [*deep-copy] semantics: copies of the variant implies copies of the value.
* [*deep-relational] semantics: comparisons between variants matches both
current types and values
* If the variant's current type is `T`, it is modeling an ['initialized] optional.
* If the variant's current type is not `T`, it is modeling an ['uninitialized]
optional.
* Testing if the variant's current type is `T` models testing if the optional
is initialized
* Trying to extract a `T` from a variant when its current type is not `T`, models
the undefined behavior of trying to access the value of an uninitialized optional
Single-element container:
* [*deep-copy] semantics: copies of the container implies copies of the value.
* [*deep-relational] semantics: comparisons between containers compare container
size and if match, contained value
* If the container is not empty (contains an object of type `T`), it is modeling
an ['initialized] optional.
* If the container is empty, it is modeling an ['uninitialized] optional.
* Testing if the container is empty models testing if the optional is
initialized
* Trying to extract a `T` from an empty container models the undefined behavior
of trying to access the value of an uninitialized optional
[endsect]
[section The semantics]
Objects of type `optional<T>` are intended to be used in places where objects of
type `T` would but which might be uninitialized. Hence, `optional<T>`'s purpose is
to formalize the additional possibly uninitialized state.
From the perspective of this role, `optional<T>` can have the same operational
semantics of `T` plus the additional semantics corresponding to this special
state.
As such, `optional<T>` could be thought of as a ['supertype] of `T`. Of course, we
can't do that in C++, so we need to compose the desired semantics using a
different mechanism.
Doing it the other way around, that is, making `optional<T>` a ['subtype] of `T`
is not only conceptually wrong but also impractical: it is not allowed to
derive from a non-class type, such as a built-in type.
We can draw from the purpose of `optional<T>` the required basic semantics:
* [*Default Construction:] To introduce a formally uninitialized wrapped
object.
* [*Direct Value Construction via copy:] To introduce a formally initialized
wrapped object whose value is obtained as a copy of some object.
* [*Deep Copy Construction:] To obtain a new yet equivalent wrapped object.
* [*Direct Value Assignment (upon initialized):] To assign a value to the
wrapped object.
* [*Direct Value Assignment (upon uninitialized):] To initialize the wrapped
object with a value obtained as a copy of some object.
* [*Assignment (upon initialized):] To assign to the wrapped object the value
of another wrapped object.
* [*Assignment (upon uninitialized):] To initialize the wrapped object with
value of another wrapped object.
* [*Deep Relational Operations (when supported by the type T):] To compare
wrapped object values taking into account the presence of uninitialized states.
* [*Value access:] To unwrap the wrapped object.
* [*Initialization state query:] To determine if the object is formally
initialized or not.
* [*Swap:] To exchange wrapped objects. (with whatever exception safety
guarantees are provided by `T`'s swap).
* [*De-initialization:] To release the wrapped object (if any) and leave the
wrapper in the uninitialized state.
Additional operations are useful, such as converting constructors and
converting assignments, in-place construction and assignment, and safe
value access via a pointer to the wrapped object or null.
[endsect]
[section The Interface]
Since the purpose of optional is to allow us to use objects with a formal
uninitialized additional state, the interface could try to follow the
interface of the underlying `T` type as much as possible. In order to choose
the proper degree of adoption of the native `T` interface, the following must
be noted: Even if all the operations supported by an instance of type `T` are
defined for the entire range of values for such a type, an `optional<T>`
extends such a set of values with a new value for which most
(otherwise valid) operations are not defined in terms of `T`.
Furthermore, since `optional<T>` itself is merely a `T` wrapper (modeling a `T`
supertype), any attempt to define such operations upon uninitialized optionals
will be totally artificial w.r.t. `T`.
This library chooses an interface which follows from `T`'s interface only for
those operations which are well defined (w.r.t the type `T`) even if any of the
operands are uninitialized. These operations include: construction,
copy-construction, assignment, swap and relational operations.
For the value access operations, which are undefined (w.r.t the type `T`) when
the operand is uninitialized, a different interface is chosen (which will be
explained next).
Also, the presence of the possibly uninitialized state requires additional
operations not provided by `T` itself which are supported by a special interface.
[heading Lexically-hinted Value Access in the presence of possibly
untitialized optional objects: The operators * and ->]
A relevant feature of a pointer is that it can have a [*null pointer value].
This is a ['special] value which is used to indicate that the pointer is not
referring to any object at all. In other words, null pointer values convey
the notion of nonexistent objects.
This meaning of the null pointer value allowed pointers to became a ['de
facto] standard for handling optional objects because all you have to do
to refer to a value which you don't really have is to use a null pointer
value of the appropriate type. Pointers have been used for decades—from
the days of C APIs to modern C++ libraries—to ['refer] to optional (that is,
possibly nonexistent) objects; particularly as optional arguments to a
function, but also quite often as optional data members.
The possible presence of a null pointer value makes the operations that
access the pointee's value possibly undefined, therefore, expressions which
use dereference and access operators, such as: `( *p = 2 )` and `( p->foo() )`,
implicitly convey the notion of optionality, and this information is tied to
the ['syntax] of the expressions. That is, the presence of operators `*` and `->`
tell by themselves —without any additional context— that the expression will
be undefined unless the implied pointee actually exist.
Such a ['de facto] idiom for referring to optional objects can be formalized
in the form of a concept: the __OPTIONAL_POINTEE__ concept.
This concept captures the syntactic usage of operators `*`, `->` and
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
or moving/copying them. The problem resides in the shallow-copy of pointer
semantics: if you need to effectively move or copy the object, pointers alone
are not enough. The problem is that copies of pointers do not imply copies of
pointees. For example, as was discussed in the motivation, pointers alone
cannot be used to return optional objects from a function because the object
must move outside from the function and into the caller's context.
A solution to the shallow-copy problem that is often used is to resort to
dynamic allocation and use a smart pointer to automatically handle the details
of this. For example, if a function is to optionally return an object `X`, it can
use `shared_ptr<X>` as the return value. However, this requires dynamic allocation
of `X`. If `X` is a built-in or small POD, this technique is very poor in terms of
required resources. Optional objects are essentially values so it is very
convenient to be able to use automatic storage and deep-copy semantics to
manipulate optional values just as we do with ordinary values. Pointers do
not have this semantics, so are inappropriate for the initialization and
transport of optional values, yet are quite convenient for handling the access
to the possible undefined value because of the idiomatic aid present in the
__OPTIONAL_POINTEE__ concept incarnated by pointers.
[heading Optional<T> as a model of OptionalPointee]
For value access operations `optional<>` uses operators `*` and `->` to
lexically warn about the possibly uninitialized state appealing to the
familiar pointer semantics w.r.t. to null pointers.
[warning
However, it is particularly important to note that `optional<>` objects
are not pointers. [_`optional<>` is not, and does not model, a pointer].
]
For instance, `optional<>` does not have shallow-copy so does not alias:
two different optionals never refer to the ['same] value unless `T` itself is
a reference (but may have ['equivalent] values).
The difference between an `optional<T>` and a pointer must be kept in mind,
particularly because the semantics of relational operators are different:
since `optional<T>` is a value-wrapper, relational operators are deep: they
compare optional values; but relational operators for pointers are shallow:
they do not compare pointee values.
As a result, you might be able to replace `optional<T>` by `T*` on some
situations but not always. Specifically, on generic code written for both,
you cannot use relational operators directly, and must use the template
functions __FUNCTION_EQUAL_POINTEES__ and __FUNCTION_LESS_POINTEES__ instead.
[endsect]
[endsect]

37
doc/12_when_to_use.qbk Normal file
View File

@ -0,0 +1,37 @@

[section When to use Optional]
It is recommended to use `optional<T>` in situations where there is exactly one, clear (to all parties) reason for having no value of type `T`, and where the lack of value is as natural as having any regular value of `T`. One example of such situation is asking the user in some GUI form to optionally specify some limit on an `int` value, but the user is allowed to say 'I want the number not to be constrained by the maximum'.
For another example, consider a config parameter specifying how many threads the application should launch. Leaving this parameter unspecified means that the application should decide itself. For yet another example, consider a function returning the index of the smallest element in a `vector`. We need to be prepared for the situation, where the `vector` is empty. Therefore a natural signature for such function would be:
template <typename T>
optional<size_t> find_smallest_elem(const std::vector<T>& vec);
Here, having received an empty `vec` and having no `size_t` to return is not a ['failure] but a ['normal], albeit irregular, situation.
Another typical situation is to indicate that we do not have a value yet, but we expect to have it later. This notion can be used in implementing solutions like lazy initialization or a two-phase initialization.
`optional` can be used to take a non-__SGI_DEFAULT_CONSTRUCTIBLE__ type `T` and create a sibling type with a default constructor. This is a way to add a ['null-state] to any type that doesn't have it already.
Sometimes type `T` already provides a built-in null-state, but it may still be useful to wrap it into `optional`. Consider `std::string`. When you read a piece of text from a GUI form or a DB table, it is hardly ever that the empty string indicates anything else but a missing text. And some data bases do not even distinguish between a null string entry and a non-null string of length 0. Still, it may be practical to use `optional<string>` to indicate in the returned type that we want to treat the empty string in a special dedicated program path:
if(boost::optional<std::string> name = ask_user_name()) {
assert(*name != "");
logon_as(*name);
}
else {
skip_logon();
}
In the example above, the assertion indicates that if we choose to use this technique, we must translate the empty string state to an optional object with no contained value (inside function `ask_user_name`).
[heading Not recommended usages]
It is not recommended to use `optional` to indicate that we were not able to compute a value because of a ['failure]. It is difficult to define what a failure is, but it usually has one common characteristic: an associated information on the cause of the failure. This can be the type and member data of an exception object, or an error code. It is a bad design to signal a failure and not inform about the cause. If you do not want to use exceptions, and do not like the fact that by returning error codes you cannot return the computed value, you can use [@https://github.com/ptal/Boost.Expected Expected] library. It is sort of __BOOST_VARIANT__ that contains either a computed value or a reason why the computation failed.
Sometimes the distinction into what is a failure and what is a valid but irregular result is blurry and depends on a particular usage and personal preference. Consider a function that converts a `string` to an `int`. Is it a failure that you cannot convert? It might in some cases, but in other you may call it exactly for the purpose of figuring out if a given `string` is convertible, and you are not even interested in the resulting value. Sometimes when a conversion fails you may not consider it a failure, but you need to know why it cannot be converted; for instance at which character it is determined that the conversion is impossible. In this case returning `optional<T>` will not suffice. Finally, there is a use case where an input string that does not represent an `int` is not a failure condition, but during the conversion we use resources whose acquisition may fail. In that case the natural representation is to both return `optional<int>` and signal failure:
optional<int> convert1(const string& str); // throws
expected<ErrorT, optional<int>> convert2(const string& str); // return either optional or error
[endsect]

View File

@ -0,0 +1,37 @@

[section Relational operators]
Type `optional<T>` is __SGI_EQUALITY_COMPARABLE__ whenever `T` is __SGI_EQUALITY_COMPARABLE__. Two optional objects containing a value compare in the same as their contained values. The uninitialized state of `optional<T>` is treated as a distinct value, equal to itself, and unequal to any value of type `T`:
boost::optional<int> oN = boost::none;
boost::optional<int> o0 = 0;
boost::optional<int> o1 = 1;
assert(oN != o0);
assert(o1 != oN);
assert(o0 != o1);
assert(oN == oN);
assert(o0 == o0);
The converting constructor from `T` as well as from `boost::none` implies the existence and semantics of the mixed comparison between `T` and `optional<T>` as well as between `none_t` and `optionl<T>`:
assert(oN != 0);
assert(o1 != boost::none);
assert(o0 != 1);
assert(oN == boost::none);
assert(o0 == 0);
This mixed comparison has a practical interpretation, which is occasionally useful:
boost::optional<int> choice = ask_user();
if (choice == 2)
start_procedure_2();
In the above example, the meaning of the comparison is 'user chose number 2'. If user chose nothing, he didn't choose number 2.
In case where `optional<T>` is compared to `none`, it is not required that `T` be __SGI_EQUALITY_COMPARABLE__.
In a similar manner, type `optional<T>` is __SGI_LESS_THAN_COMPARABLE__ whenever `T` is __SGI_LESS_THAN_COMPARABLE__. The optional object containing no value is compared less than any value of `T`. To illustrate this, if the default ordering of `size_t` is {`0`, `1`, `2`, ...}, the default ordering of `optional<size_t>` is {`boost::none`, `0`, `1`, `2`, ...}. This order does not have a practical interpretation. The goal is to have any semantically correct default ordering in order for `optional<T>` to be usable in ordered associative containers (wherever `T` is usable).
Mixed relational operators are the only case where the contained value of an optional object can be inspected without the usage of value accessing function (`operator*`, `value`, `value_or`).
[endsect]

View 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]

View 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
View 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]

View 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]

View File

@ -0,0 +1,38 @@

[section Type requirements]
The very minimum requirement of `optional<T>` is that `T` is a complete type and that it has a publicly accessible destructor. `T` doesn't even need to be constructible. You can use a very minimum interface:
optional<T> o; // uninitialized
assert(o == none); // check if initialized
assert(!o); //
o.value(); // always throws
But this is practically useless. In order for `optional<T>` to be able to do anything useful and offer all the spectrum of ways of accessing the contained value, `T` needs to have at least one accessible constructor. In that case you need to initialize the optional object with function `emplace()`, or if your compiler does not support it, resort to [link boost_optional.tutorial.in_place_factories In-Place Factories]:
optional<T> o;
o.emplace("T", "ctor", "params");
If `T` is __MOVE_CONSTRUCTIBLE__, `optional<T>` is also __MOVE_CONSTRUCTIBLE__ and can be easily initialized from an rvalue of type `T` and be passed by value:
optional<T> o = make_T();
optional<T> p = optional<T>();
If `T` is __COPY_CONSTRUCTIBLE__, `optional<T>` is also __COPY_CONSTRUCTIBLE__ and can be easily initialized from an lvalue of type `T`:
T v = make_T();
optional<T> o = v;
optional<T> p = o;
If `T` is not `MoveAssignable`, it is still possible to reset the value of `optional<T>` using function `emplace()`:
optional<const T> o = make_T();
o.emplace(make_another_T());
If `T` is `Moveable` (both __MOVE_CONSTRUCTIBLE__ and `MoveAssignable`) then `optional<T>` is also `Moveable` and additionally can be constructed and assigned from an rvalue of type `T`.
Similarly, if `T` is `Copyable` (both __COPY_CONSTRUCTIBLE__ and `CopyAssignable`) then `optional<T>` is also `Copyable` and additionally can be constructed and assigned from an lvalue of type `T`.
`T` ['is not] required to be __SGI_DEFAULT_CONSTRUCTIBLE__.
[endsect]

1288
doc/20_reference.qbk Normal file

File diff suppressed because it is too large Load Diff

81
doc/90_dependencies.qbk Normal file
View File

@ -0,0 +1,81 @@
[/
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 Dependencies and Portability]
[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]
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 `T&`:
const int i = 0;
optional<const int&> or1;
optional<const int&> or2 = i; // not portable
or1 = i; // not portable
optional<const int&> or3(i); // portable
or1 = optional<const int&>(i); // portable
In order to check if your compiler correctly implements reference binding use this test program.
#include <cassert>
const int global_i = 0;
struct TestingReferenceBinding
{
TestingReferenceBinding(const int& ii)
{
assert(&ii == &global_i);
}
void operator=(const int& ii)
{
assert(&ii == &global_i);
}
void operator=(int&&) // remove this if your compiler doesn't have rvalue refs
{
assert(false);
}
};
int main()
{
const int& iref = global_i;
assert(&iref == &global_i);
TestingReferenceBinding ttt = global_i;
ttt = global_i;
TestingReferenceBinding ttt2 = iref;
ttt2 = iref;
}
[endsect]
[endsect]

View File

@ -0,0 +1,62 @@
[/
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 Acknowledgements]
[heading Pre-formal review]
* Peter Dimov suggested the name 'optional', and was the first to point out
the need for aligned storage.
* Douglas Gregor developed 'type_with_alignment', and later Eric Friedman
coded 'aligned_storage', which are the core of the optional class
implementation.
* Andrei Alexandrescu and Brian Parker also worked with aligned storage
techniques and their work influenced the current implementation.
* Gennadiy Rozental made extensive and important comments which shaped the
design.
* Vesa Karvonen and Douglas Gregor made quite useful comparisons between
optional, variant and any; and made other relevant comments.
* Douglas Gregor and Peter Dimov commented on comparisons and evaluation
in boolean contexts.
* Eric Friedman helped understand the issues involved with aligned storage,
move/copy operations and exception safety.
* Many others have participated with useful comments: Aleksey Gurotov,
Kevlin Henney, David Abrahams, and others I can't recall.
[heading Post-formal review]
* William Kempf carefully considered the originally proposed interface
and suggested the new interface which is currently used. He also started and
fueled the discussion about the analogy optional<>/smart pointer and about
relational operators.
* Peter Dimov, Joel de Guzman, David Abrahams, Tanton Gibbs and Ian Hanson
focused on the relational semantics of optional (originally undefined);
concluding with the fact that the pointer-like interface doesn't make it a
pointer so it shall have deep relational operators.
* Augustus Saunders also explored the different relational semantics between
optional<> and a pointer and developed the OptionalPointee concept as an aid
against potential conflicts on generic code.
* Joel de Guzman noticed that optional<> can be seen as an API on top of
variant<T,nil_t>.
* Dave Gomboc explained the meaning and usage of the Haskell analog to
optional<>: the Maybe type constructor (analogy originally pointed out by
David Sankel).
* Other comments were posted by Vincent Finn, Anthony Williams, Ed Brey,
Rob Stewart, and others.
* Joel de Guzman made the case for the support of references and helped
with the proper semantics.
* Mat Marcus shown the virtues of a value-oriented interface, influencing
the current design, and contributed the idea of "none".
* Vladimir Batov's design of Boost.Convert library motivated the development
of value accessors for `optional`: functions `value`, `value_or`, `value_or_eval`.
[endsect]

39
doc/Jamfile.v2 Normal file
View File

@ -0,0 +1,39 @@
# 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)
# Quickbook
# -----------------------------------------------------------------------------
using boostbook ;
import quickbook ;
path-constant images : html ;
xml optional
:
00_optional.qbk
;
boostbook standalone
:
optional
:
<format>html:<xsl:param>boost.root=../../../..
<format>html:<xsl:param>boost.libraries=../../../../libs/libraries.htm
<xsl:param>chapter.autolabel=0
<xsl:param>chunk.section.depth=8
<xsl:param>toc.section.depth=2
<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
<format>docbook:<auto-index-internal>on
;

View File

@ -0,0 +1,108 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>A note about optional&lt;bool&gt;</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&#160;1.&#160;Boost.Optional">
<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;Boost.Optional">
<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">
<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="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">
<a name="boost_optional.a_note_about_optional_bool_"></a><a class="link" href="a_note_about_optional_bool_.html" title="A note about optional&lt;bool&gt;">A note about
optional&lt;bool&gt;</a>
</h2></div></div></div>
<p>
<code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="keyword">bool</span><span class="special">&gt;</span></code> should
be used with special caution and consideration.
</p>
<p>
First, it is functionally similar to a tristate boolean (false, maybe, true)
&#8212;such as <a href="../../../../../doc/html/tribool.html" target="_top">boost::tribool</a>&#8212;
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">&lt;</span><span class="keyword">bool</span><span class="special">&gt;</span></code>. It
should be carefully considered if an <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="keyword">bool</span><span class="special">&gt;</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">&lt;&gt;</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">&lt;</span><span class="keyword">bool</span><span class="special">&gt;</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">&lt;</span><span class="keyword">bool</span><span class="special">&gt;</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">&lt;</span><span class="keyword">bool</span><span class="special">&gt;</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">&lt;&gt;</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 &#169; 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright &#169; 2014 Andrzej Krzemie&#324;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="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>

View File

@ -0,0 +1,130 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Acknowledgements</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="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>
<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/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">
<a name="boost_optional.acknowledgements"></a><a class="link" href="acknowledgements.html" title="Acknowledgements">Acknowledgements</a>
</h2></div></div></div>
<h4>
<a name="boost_optional.acknowledgements.h0"></a>
<span class="phrase"><a name="boost_optional.acknowledgements.pre_formal_review"></a></span><a class="link" href="acknowledgements.html#boost_optional.acknowledgements.pre_formal_review">Pre-formal
review</a>
</h4>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
Peter Dimov suggested the name 'optional', and was the first to point out
the need for aligned storage.
</li>
<li class="listitem">
Douglas Gregor developed 'type_with_alignment', and later Eric Friedman
coded 'aligned_storage', which are the core of the optional class implementation.
</li>
<li class="listitem">
Andrei Alexandrescu and Brian Parker also worked with aligned storage techniques
and their work influenced the current implementation.
</li>
<li class="listitem">
Gennadiy Rozental made extensive and important comments which shaped the
design.
</li>
<li class="listitem">
Vesa Karvonen and Douglas Gregor made quite useful comparisons between
optional, variant and any; and made other relevant comments.
</li>
<li class="listitem">
Douglas Gregor and Peter Dimov commented on comparisons and evaluation
in boolean contexts.
</li>
<li class="listitem">
Eric Friedman helped understand the issues involved with aligned storage,
move/copy operations and exception safety.
</li>
<li class="listitem">
Many others have participated with useful comments: Aleksey Gurotov, Kevlin
Henney, David Abrahams, and others I can't recall.
</li>
</ul></div>
<h4>
<a name="boost_optional.acknowledgements.h1"></a>
<span class="phrase"><a name="boost_optional.acknowledgements.post_formal_review"></a></span><a class="link" href="acknowledgements.html#boost_optional.acknowledgements.post_formal_review">Post-formal
review</a>
</h4>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
William Kempf carefully considered the originally proposed interface and
suggested the new interface which is currently used. He also started and
fueled the discussion about the analogy optional&lt;&gt;/smart pointer
and about relational operators.
</li>
<li class="listitem">
Peter Dimov, Joel de Guzman, David Abrahams, Tanton Gibbs and Ian Hanson
focused on the relational semantics of optional (originally undefined);
concluding with the fact that the pointer-like interface doesn't make it
a pointer so it shall have deep relational operators.
</li>
<li class="listitem">
Augustus Saunders also explored the different relational semantics between
optional&lt;&gt; and a pointer and developed the OptionalPointee concept
as an aid against potential conflicts on generic code.
</li>
<li class="listitem">
Joel de Guzman noticed that optional&lt;&gt; can be seen as an API on top
of variant&lt;T,nil_t&gt;.
</li>
<li class="listitem">
Dave Gomboc explained the meaning and usage of the Haskell analog to optional&lt;&gt;:
the Maybe type constructor (analogy originally pointed out by David Sankel).
</li>
<li class="listitem">
Other comments were posted by Vincent Finn, Anthony Williams, Ed Brey,
Rob Stewart, and others.
</li>
<li class="listitem">
Joel de Guzman made the case for the support of references and helped with
the proper semantics.
</li>
<li class="listitem">
Mat Marcus shown the virtues of a value-oriented interface, influencing
the current design, and contributed the idea of "none".
</li>
<li class="listitem">
Vladimir Batov's design of Boost.Convert library motivated the development
of value accessors for <code class="computeroutput"><span class="identifier">optional</span></code>:
functions <code class="computeroutput"><span class="identifier">value</span></code>, <code class="computeroutput"><span class="identifier">value_or</span></code>, <code class="computeroutput"><span class="identifier">value_or_eval</span></code>.
</li>
</ul></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 &#169; 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright &#169; 2014 Andrzej Krzemie&#324;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/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>

View File

@ -0,0 +1,125 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<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="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>
<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/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">
<a name="boost_optional.acknowledgments"></a><a class="link" href="acknowledgments.html" title="Acknowledgments">Acknowledgments</a>
</h2></div></div></div>
<h4>
<a name="boost_optional.acknowledgments.h0"></a>
<span class="phrase"><a name="boost_optional.acknowledgments.pre_formal_review"></a></span><a class="link" href="acknowledgments.html#boost_optional.acknowledgments.pre_formal_review">Pre-formal
review</a>
</h4>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
Peter Dimov suggested the name 'optional', and was the first to point out
the need for aligned storage.
</li>
<li class="listitem">
Douglas Gregor developed 'type_with_alignment', and later Eric Friedman
coded 'aligned_storage', which are the core of the optional class implementation.
</li>
<li class="listitem">
Andrei Alexandrescu and Brian Parker also worked with aligned storage techniques
and their work influenced the current implementation.
</li>
<li class="listitem">
Gennadiy Rozental made extensive and important comments which shaped the
design.
</li>
<li class="listitem">
Vesa Karvonen and Douglas Gregor made quite useful comparisons between
optional, variant and any; and made other relevant comments.
</li>
<li class="listitem">
Douglas Gregor and Peter Dimov commented on comparisons and evaluation
in boolean contexts.
</li>
<li class="listitem">
Eric Friedman helped understand the issues involved with aligned storage,
move/copy operations and exception safety.
</li>
<li class="listitem">
Many others have participated with useful comments: Aleksey Gurotov, Kevlin
Henney, David Abrahams, and others I can't recall.
</li>
</ul></div>
<h4>
<a name="boost_optional.acknowledgments.h1"></a>
<span class="phrase"><a name="boost_optional.acknowledgments.post_formal_review"></a></span><a class="link" href="acknowledgments.html#boost_optional.acknowledgments.post_formal_review">Post-formal
review</a>
</h4>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
William Kempf carefully considered the originally proposed interface and
suggested the new interface which is currently used. He also started and
fueled the discussion about the analogy optional&lt;&gt;/smart pointer
and about relational operators.
</li>
<li class="listitem">
Peter Dimov, Joel de Guzman, David Abrahams, Tanton Gibbs and Ian Hanson
focused on the relational semantics of optional (originally undefined);
concluding with the fact that the pointer-like interface doesn't make it
a pointer so it shall have deep relational operators.
</li>
<li class="listitem">
Augustus Saunders also explored the different relational semantics between
optional&lt;&gt; and a pointer and developed the OptionalPointee concept
as an aid against potential conflicts on generic code.
</li>
<li class="listitem">
Joel de Guzman noticed that optional&lt;&gt; can be seen as an API on top
of variant&lt;T,nil_t&gt;.
</li>
<li class="listitem">
Dave Gomboc explained the meaning and usage of the Haskell analog to optional&lt;&gt;:
the Maybe type constructor (analogy originally pointed out by David Sankel).
</li>
<li class="listitem">
Other comments were posted by Vincent Finn, Anthony Williams, Ed Brey,
Rob Stewart, and others.
</li>
<li class="listitem">
Joel de Guzman made the case for the support of references and helped with
the proper semantics.
</li>
<li class="listitem">
Mat Marcus shown the virtues of a value-oriented interface, influencing
the current design, and contributed the idea of "none".
</li>
</ul></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 &#169; 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright &#169; 2014 Andrzej Krzemie&#324;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/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>

View File

@ -0,0 +1,89 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<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="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>
<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="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.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.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>
The implementation uses the following other Boost modules:
</p>
<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>
<td align="left"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright &#169; 2014 Andrzej Krzemie&#324;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="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>

View File

@ -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="../acknowledgements.html" title="Acknowledgements">
</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="../acknowledgements.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">&amp;</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">&lt;</span><span class="keyword">const</span> <span class="keyword">int</span><span class="special">&amp;&gt;</span> <span class="identifier">or1</span><span class="special">;</span>
<span class="identifier">optional</span><span class="special">&lt;</span><span class="keyword">const</span> <span class="keyword">int</span><span class="special">&amp;&gt;</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">&lt;</span><span class="keyword">const</span> <span class="keyword">int</span><span class="special">&amp;&gt;</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">&lt;</span><span class="keyword">const</span> <span class="keyword">int</span><span class="special">&amp;&gt;(</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">&lt;</span><span class="identifier">cassert</span><span class="special">&gt;</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">&amp;</span> <span class="identifier">ii</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">assert</span><span class="special">(&amp;</span><span class="identifier">ii</span> <span class="special">==</span> <span class="special">&amp;</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">&amp;</span> <span class="identifier">ii</span><span class="special">)</span>
<span class="special">{</span>
<span class="identifier">assert</span><span class="special">(&amp;</span><span class="identifier">ii</span> <span class="special">==</span> <span class="special">&amp;</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">&amp;&amp;)</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">&amp;</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">(&amp;</span><span class="identifier">iref</span> <span class="special">==</span> <span class="special">&amp;</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 &#169; 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright &#169; 2014 Andrzej Krzemie&#324;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="../acknowledgements.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,412 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Development</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&#160;1.&#160;Boost.Optional">
<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;Boost.Optional">
<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">
<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="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">
<a name="boost_optional.development"></a><a class="link" href="development.html" title="Development">Development</a>
</h2></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="development.html#boost_optional.development.the_models">The models</a></span></dt>
<dt><span class="section"><a href="development.html#boost_optional.development.the_semantics">The semantics</a></span></dt>
<dt><span class="section"><a href="development.html#boost_optional.development.the_interface">The Interface</a></span></dt>
</dl></div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_optional.development.the_models"></a><a class="link" href="development.html#boost_optional.development.the_models" title="The models">The models</a>
</h3></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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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>&#8212;where <code class="computeroutput"><span class="identifier">nil_t</span></code>
is some stateless POD&#8212;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">&lt;</span><span class="identifier">T</span><span class="special">,</span><span class="identifier">nil_t</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">,</span><span class="identifier">nil_t</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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&#8212;i.e.
possibly uninitialized&#8212;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><h3 class="title">
<a name="boost_optional.development.the_semantics"></a><a class="link" href="development.html#boost_optional.development.the_semantics" title="The semantics">The semantics</a>
</h3></div></div></div>
<p>
Objects of type <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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><h3 class="title">
<a name="boost_optional.development.the_interface"></a><a class="link" href="development.html#boost_optional.development.the_interface" title="The Interface">The Interface</a>
</h3></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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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>
<h5>
<a name="boost_optional.development.the_interface.h0"></a>
<span class="phrase"><a name="boost_optional.development.the_interface.lexically_hinted_value_access_in_the_presence_of_possibly_untitialized_optional_objects__the_operators___and___gt_"></a></span><a class="link" href="development.html#boost_optional.development.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 -&gt;</a>
</h5>
<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&#8212;from
the days of C APIs to modern C++ libraries&#8212;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">-&gt;</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">-&gt;</span></code> tell by themselves
&#8212;without any additional context&#8212; 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">-&gt;</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">&lt;</span><span class="identifier">X</span><span class="special">&gt;</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>
<h5>
<a name="boost_optional.development.the_interface.h1"></a>
<span class="phrase"><a name="boost_optional.development.the_interface.optional_lt_t_gt__as_a_model_of_optionalpointee"></a></span><a class="link" href="development.html#boost_optional.development.the_interface.optional_lt_t_gt__as_a_model_of_optionalpointee">Optional&lt;T&gt;
as a model of OptionalPointee</a>
</h5>
<p>
For value access operations <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;&gt;</span></code> uses operators <code class="computeroutput"><span class="special">*</span></code>
and <code class="computeroutput"><span class="special">-&gt;</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">&lt;&gt;</span></code> objects are not pointers. <span class="underline"><code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;&gt;</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">&lt;&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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>
<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 &#169; 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright &#169; 2014 Andrzej Krzemie&#324;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="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>

View 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&#160;1.&#160;Boost.Optional">
<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;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">&lt;</span><span class="identifier">point</span><span class="special">,</span><span class="keyword">bool</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">,</span><span class="keyword">bool</span><span class="special">&gt;</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">&lt;</span><span class="keyword">char</span><span class="special">,</span><span class="keyword">bool</span><span class="special">&gt;</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">&lt;</span><span class="identifier">point</span><span class="special">,</span><span class="keyword">bool</span><span class="special">&gt;</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">&lt;</span><span class="identifier">point</span><span class="special">,</span><span class="keyword">bool</span><span class="special">&gt;</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 &#169; 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright &#169; 2014 Andrzej Krzemie&#324;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>

View File

@ -0,0 +1,147 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Examples</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&#160;1.&#160;Boost.Optional">
<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;Boost.Optional">
<link rel="prev" href="detailed_semantics.html" title="Detailed 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="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="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">
<a name="boost_optional.examples"></a><a class="link" href="examples.html" title="Examples">Examples</a>
</h2></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="examples.html#boost_optional.examples.optional_return_values">Optional
return values</a></span></dt>
<dt><span class="section"><a href="examples.html#boost_optional.examples.optional_local_variables">Optional
local variables</a></span></dt>
<dt><span class="section"><a href="examples.html#boost_optional.examples.optional_data_members">Optional
data members</a></span></dt>
<dt><span class="section"><a href="examples.html#boost_optional.examples.bypassing_expensive_unnecessary_default_construction">Bypassing
expensive unnecessary default construction</a></span></dt>
</dl></div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_optional.examples.optional_return_values"></a><a class="link" href="examples.html#boost_optional.examples.optional_return_values" title="Optional return values">Optional
return values</a>
</h3></div></div></div>
<pre class="programlisting"><span class="identifier">optional</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt;</span> <span class="identifier">get_async_input</span><span class="special">()</span>
<span class="special">{</span>
<span class="keyword">if</span> <span class="special">(</span> <span class="special">!</span><span class="identifier">queue</span><span class="special">.</span><span class="identifier">empty</span><span class="special">()</span> <span class="special">)</span>
<span class="keyword">return</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt;(</span><span class="identifier">queue</span><span class="special">.</span><span class="identifier">top</span><span class="special">());</span>
<span class="keyword">else</span> <span class="keyword">return</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt;();</span> <span class="comment">// uninitialized</span>
<span class="special">}</span>
<span class="keyword">void</span> <span class="identifier">receive_async_message</span><span class="special">()</span>
<span class="special">{</span>
<span class="identifier">optional</span><span class="special">&lt;</span><span class="keyword">char</span><span class="special">&gt;</span> <span class="identifier">rcv</span> <span class="special">;</span>
<span class="comment">// The safe boolean conversion from 'rcv' is used here.</span>
<span class="keyword">while</span> <span class="special">(</span> <span class="special">(</span><span class="identifier">rcv</span> <span class="special">=</span> <span class="identifier">get_async_input</span><span class="special">())</span> <span class="special">&amp;&amp;</span> <span class="special">!</span><span class="identifier">timeout</span><span class="special">()</span> <span class="special">)</span>
<span class="identifier">output</span><span class="special">(*</span><span class="identifier">rcv</span><span class="special">);</span>
<span class="special">}</span>
</pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_optional.examples.optional_local_variables"></a><a class="link" href="examples.html#boost_optional.examples.optional_local_variables" title="Optional local variables">Optional
local variables</a>
</h3></div></div></div>
<pre class="programlisting"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">string</span><span class="special">&gt;</span> <span class="identifier">name</span> <span class="special">;</span>
<span class="keyword">if</span> <span class="special">(</span> <span class="identifier">database</span><span class="special">.</span><span class="identifier">open</span><span class="special">()</span> <span class="special">)</span>
<span class="special">{</span>
<span class="identifier">name</span> <span class="special">=</span> <span class="identifier">database</span><span class="special">.</span><span class="identifier">lookup</span><span class="special">(</span><span class="identifier">employer_name</span><span class="special">)</span> <span class="special">;</span>
<span class="special">}</span>
<span class="keyword">else</span>
<span class="special">{</span>
<span class="keyword">if</span> <span class="special">(</span> <span class="identifier">can_ask_user</span> <span class="special">)</span>
<span class="identifier">name</span> <span class="special">=</span> <span class="identifier">user</span><span class="special">.</span><span class="identifier">ask</span><span class="special">(</span><span class="identifier">employer_name</span><span class="special">)</span> <span class="special">;</span>
<span class="special">}</span>
<span class="keyword">if</span> <span class="special">(</span> <span class="identifier">name</span> <span class="special">)</span>
<span class="identifier">print</span><span class="special">(*</span><span class="identifier">name</span><span class="special">);</span>
<span class="keyword">else</span> <span class="identifier">print</span><span class="special">(</span><span class="string">"employer's name not found!"</span><span class="special">);</span>
</pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_optional.examples.optional_data_members"></a><a class="link" href="examples.html#boost_optional.examples.optional_data_members" title="Optional data members">Optional
data members</a>
</h3></div></div></div>
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">figure</span>
<span class="special">{</span>
<span class="keyword">public</span><span class="special">:</span>
<span class="identifier">figure</span><span class="special">()</span>
<span class="special">{</span>
<span class="comment">// data member 'm_clipping_rect' is uninitialized at this point.</span>
<span class="special">}</span>
<span class="keyword">void</span> <span class="identifier">clip_in_rect</span> <span class="special">(</span> <span class="identifier">rect</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">rect</span> <span class="special">)</span>
<span class="special">{</span>
<span class="special">....</span>
<span class="identifier">m_clipping_rect</span> <span class="special">=</span> <span class="identifier">rect</span> <span class="special">;</span> <span class="comment">// initialized here.</span>
<span class="special">}</span>
<span class="keyword">void</span> <span class="identifier">draw</span> <span class="special">(</span> <span class="identifier">canvas</span><span class="special">&amp;</span> <span class="identifier">cvs</span> <span class="special">)</span>
<span class="special">{</span>
<span class="keyword">if</span> <span class="special">(</span> <span class="identifier">m_clipping_rect</span> <span class="special">)</span>
<span class="identifier">do_clipping</span><span class="special">(*</span><span class="identifier">m_clipping_rect</span><span class="special">);</span>
<span class="identifier">cvs</span><span class="special">.</span><span class="identifier">drawXXX</span><span class="special">(..);</span>
<span class="special">}</span>
<span class="comment">// this can return NULL.</span>
<span class="identifier">rect</span> <span class="keyword">const</span><span class="special">*</span> <span class="identifier">get_clipping_rect</span><span class="special">()</span> <span class="special">{</span> <span class="keyword">return</span> <span class="identifier">get_pointer</span><span class="special">(</span><span class="identifier">m_clipping_rect</span><span class="special">);</span> <span class="special">}</span>
<span class="keyword">private</span> <span class="special">:</span>
<span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">rect</span><span class="special">&gt;</span> <span class="identifier">m_clipping_rect</span> <span class="special">;</span>
<span class="special">};</span>
</pre>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_optional.examples.bypassing_expensive_unnecessary_default_construction"></a><a class="link" href="examples.html#boost_optional.examples.bypassing_expensive_unnecessary_default_construction" title="Bypassing expensive unnecessary default construction">Bypassing
expensive unnecessary default construction</a>
</h3></div></div></div>
<pre class="programlisting"><span class="keyword">class</span> <span class="identifier">ExpensiveCtor</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">Fred</span>
<span class="special">{</span>
<span class="identifier">Fred</span><span class="special">()</span> <span class="special">:</span> <span class="identifier">mLargeVector</span><span class="special">(</span><span class="number">10000</span><span class="special">)</span> <span class="special">{}</span>
<span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">ExpensiveCtor</span><span class="special">&gt;</span> <span class="special">&gt;</span> <span class="identifier">mLargeVector</span> <span class="special">;</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"></td>
<td align="right"><div class="copyright-footer">Copyright &#169; 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright &#169; 2014 Andrzej Krzemie&#324;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="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="optional_references.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,170 @@
<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="Chapter&#160;1.&#160;Boost.Optional">
<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;Boost.Optional">
<link rel="prev" href="a_note_about_optional_bool_.html" title="A note about optional&lt;bool&gt;">
<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="../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="type_requirements.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.exception_safety_guarantees"></a><a class="link" href="exception_safety_guarantees.html" title="Exception Safety Guarantees">Exception Safety
Guarantees</a>
</h2></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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="keyword">operator</span><span class="special">=</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="special">)</span></code>
</li>
<li class="listitem">
<code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</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">&amp;</span> <span class="special">)</span></code>
</li>
<li class="listitem">
<code class="computeroutput"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">&gt;</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="keyword">operator</span><span class="special">=</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="special">)</span></code>
</li>
<li class="listitem">
<code class="computeroutput"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">InPlaceFactory</span><span class="special">&gt;</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</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">&amp;</span>
<span class="special">)</span></code>
</li>
<li class="listitem">
<code class="computeroutput"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">TypedInPlaceFactory</span><span class="special">&gt;</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</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">&amp;</span>
<span class="special">)</span> </code>
</li>
<li class="listitem">
<code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">reset</span><span class="special">(</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&amp;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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>
<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>
</h4>
<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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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 &#169; 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright &#169; 2014 Andrzej Krzemie&#324;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="../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="type_requirements.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,55 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Implementation Notes</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&#160;1.&#160;Boost.Optional">
<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;Boost.Optional">
<link rel="prev" href="type_requirements.html" title="Type requirements">
<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>
<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="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="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">
<a name="boost_optional.implementation_notes"></a><a class="link" href="implementation_notes.html" title="Implementation Notes">Implementation Notes</a>
</h2></div></div></div>
<p>
<code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code> is
currently implemented using a custom aligned storage facility built from <code class="computeroutput"><span class="identifier">alignment_of</span></code> and <code class="computeroutput"><span class="identifier">type_with_alignment</span></code>
(both from Type Traits). It uses a separate boolean flag to indicate the initialization
state. Placement new with <code class="computeroutput"><span class="identifier">T</span></code>'s
copy/move constructor and <code class="computeroutput"><span class="identifier">T</span></code>'s
destructor are explicitly used to initialize, copy, move and destroy optional
values. As a result, <code class="computeroutput"><span class="identifier">T</span></code>'s default
constructor is effectively by-passed, but the exception guarantees are basic.
It is planned to replace the current implementation with another with stronger
exception safety, such as a future <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">variant</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 &#169; 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright &#169; 2014 Andrzej Krzemie&#324;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="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="dependencies_and_portability.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,196 @@
<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="Chapter&#160;1.&#160;Boost.Optional">
<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;Boost.Optional">
<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&lt;bool&gt;">
</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="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">
<a name="boost_optional.in_place_factories"></a><a class="link" href="in_place_factories.html" title="In-Place Factories">In-Place Factories</a>
</h2></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">&amp;</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">&amp;</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">&lt;</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">&gt;</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">&amp;</span> <span class="identifier">a0</span><span class="special">,</span> <span class="identifier">A1</span> <span class="keyword">const</span><span class="special">&amp;</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">&amp;</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">&amp;</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">(&amp;</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">&lt;</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">&gt;(</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">&lt;</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">&gt;</span>
<span class="identifier">InPlaceFactoryN</span> <span class="special">&lt;</span><span class="identifier">A0</span><span class="special">,...,</span><span class="identifier">AN</span><span class="special">&gt;</span> <span class="identifier">in_place</span> <span class="special">(</span> <span class="identifier">A0</span> <span class="keyword">const</span><span class="special">&amp;</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">&amp;</span> <span class="identifier">aN</span><span class="special">)</span> <span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</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">&gt;</span>
<span class="identifier">TypedInPlaceFactoryN</span> <span class="special">&lt;</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">&gt;</span> <span class="identifier">in_place</span> <span class="special">(</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">a0</span><span class="special">,</span> <span class="identifier">A0</span> <span class="keyword">const</span><span class="special">&amp;</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">&amp;</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">&amp;</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">&lt;</span> <span class="keyword">class</span> <span class="identifier">InPlaceFactory</span> <span class="special">&gt;</span>
<span class="identifier">W</span> <span class="special">(</span> <span class="identifier">InPlaceFactory</span> <span class="keyword">const</span><span class="special">&amp;</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">&lt;</span><span class="identifier">X</span><span class="special">&gt;</span><span class="identifier">construct</span><span class="special">(&amp;</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 &#169; 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright &#169; 2014 Andrzej Krzemie&#324;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="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>

View File

@ -0,0 +1,128 @@
<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&#160;1.&#160;Boost.Optional">
<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;Boost.Optional">
<link rel="prev" href="../index.html" title="Chapter&#160;1.&#160;Boost.Optional">
<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="../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="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.motivation"></a><a class="link" href="motivation.html" title="Motivation">Motivation</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">&lt;</span><span class="identifier">point</span><span class="special">,</span><span class="keyword">bool</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">,</span><span class="keyword">bool</span><span class="special">&gt;</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">&lt;</span><span class="keyword">char</span><span class="special">,</span><span class="keyword">bool</span><span class="special">&gt;</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">&lt;</span><span class="identifier">point</span><span class="special">,</span><span class="keyword">bool</span><span class="special">&gt;</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">&lt;</span><span class="identifier">point</span><span class="special">,</span><span class="keyword">bool</span><span class="special">&gt;</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 &#169; 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright &#169; 2014 Andrzej Krzemie&#324;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="development.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,114 @@
<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="Chapter&#160;1.&#160;Boost.Optional">
<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;Boost.Optional">
<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">
<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="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">
<a name="boost_optional.optional_references"></a><a class="link" href="optional_references.html" title="Optional references">Optional references</a>
</h2></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">&amp;</span></code>, and to some extent, <code class="computeroutput"><span class="identifier">T</span>
<span class="keyword">const</span><span class="special">&amp;</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">&lt;</span><span class="identifier">T</span><span class="special">&amp;&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&amp;&gt;</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>
<h4>
<a name="boost_optional.optional_references.h0"></a>
<span class="phrase"><a name="boost_optional.optional_references.rvalue_references"></a></span><a class="link" href="optional_references.html#boost_optional.optional_references.rvalue_references">Rvalue
references</a>
</h4>
<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">&amp;</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">&lt;</span><span class="keyword">const</span> <span class="keyword">int</span><span class="special">&amp;&gt;</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 &#169; 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright &#169; 2014 Andrzej Krzemie&#324;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="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>

View File

@ -0,0 +1,169 @@
<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 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 exists 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">&lt;</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">&gt;</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</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">&amp;</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">&lt;</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">&gt;</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">&amp;</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">optional</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</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">optional</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</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">-&gt;</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">&amp;)</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>.
Finally, you can provide a callback to be called when trying to access the
contained value fails:
</p>
<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">fallback_to_default</span><span class="special">()</span>
<span class="special">{</span>
<span class="identifier">cerr</span> <span class="special">&lt;&lt;</span> <span class="string">"could not convert; using -1 instead"</span> <span class="special">&lt;&lt;</span> <span class="identifier">endl</span><span class="special">;</span>
<span class="keyword">return</span> <span class="special">-</span><span class="number">1</span><span class="special">;</span>
<span class="special">}</span>
<span class="keyword">int</span> <span class="identifier">l</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_eval</span><span class="special">(</span><span class="identifier">fallback_to_default</span><span class="special">);</span>
</pre>
<p>
This will call the provided callback and return whatever the callback returns.
The callback can have side effects: they will only be observed when the optional
object does not contain a value.
</p>
<p>
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">optional</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</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">&amp;</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">&gt;&gt;</span> <span class="identifier">i</span><span class="special">)</span> <span class="special">&amp;&amp;</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">&lt;</span><span class="keyword">char</span><span class="special">&gt;::</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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 &#169; 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright &#169; 2014 Andrzej Krzemie&#324;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>

View File

@ -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">&lt;</span><span class="identifier">Date</span><span class="special">,</span> <span class="identifier">Date</span><span class="special">&gt;</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 <a href="../../../../../tuple/index.html" target="_top">Boost.Tuple</a>
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">&lt;</span><span class="identifier">Date</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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 &#169; 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright &#169; 2014 Andrzej Krzemie&#324;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>

View File

@ -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">optional</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</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">&amp;</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">optional</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</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">&gt;&gt;</span> <span class="identifier">i</span><span class="special">)</span> <span class="special">&amp;&amp;</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">&lt;</span><span class="keyword">char</span><span class="special">&gt;::</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">&lt;</span><span class="keyword">int</span><span class="special">&gt;</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 'mixed' 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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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 the contained value using <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 &#169; 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright &#169; 2014 Andrzej Krzemie&#324;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>

View File

@ -0,0 +1,94 @@
<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="keyword">mutable</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="keyword">const</span> <span class="identifier">Resource</span><span class="special">&gt;</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="keyword">const</span> <span class="identifier">Resource</span><span class="special">&amp;</span> <span class="identifier">getResource</span><span class="special">()</span> <span class="keyword">const</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"><code class="computeroutput"><span class="identifier">DefaultConstructible</span></code></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 &#169; 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright &#169; 2014 Andrzej Krzemie&#324;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>

View 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&#160;1.&#160;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">&lt;</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">&gt;</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">optionl</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</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">&amp;</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">&lt;</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">&gt;</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">&amp;</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">&lt;</span><span class="keyword">int</span><span class="special">&gt;</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">&lt;</span><span class="keyword">int</span><span class="special">&gt;</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">-&gt;</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">&amp;)</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">&lt;</span><span class="keyword">int</span><span class="special">&gt;</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">&amp;</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">&gt;&gt;</span> <span class="identifier">i</span><span class="special">)</span> <span class="special">&amp;&amp;</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">&lt;</span><span class="keyword">char</span><span class="special">&gt;::</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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 &#169; 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright &#169; 2014 Andrzej Krzemie&#324;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>

View File

@ -0,0 +1,64 @@
<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">&lt;</span><span class="keyword">int</span><span class="special">&gt;</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">&lt;</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;,</span> <span class="keyword">int</span><span class="special">&gt;</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">&lt;</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">&lt;</span><span class="keyword">int</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>
is <a href="http://www.sgi.com/tech/stl/LessThanComparable.html" target="_top"><code class="computeroutput"><span class="identifier">LessThanComparable</span></code></a> whenever <code class="computeroutput"><span class="identifier">T</span></code> is <a href="http://www.sgi.com/tech/stl/LessThanComparable.html" target="_top"><code class="computeroutput"><span class="identifier">LessThanComparable</span></code></a>. 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>.
</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 &#169; 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright &#169; 2014 Andrzej Krzemie&#324;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>

View File

@ -0,0 +1,148 @@
<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="Chapter&#160;1.&#160;Boost.Optional">
<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;Boost.Optional">
<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="../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="in_place_factories.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.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>
</h2></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">&lt;</span><span class="identifier">T</span><span class="special">&amp;&gt;</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">&amp;</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">&lt;</span><span class="keyword">int</span><span class="special">&amp;&gt;</span> <span class="identifier">ora</span> <span class="special">;</span>
<span class="identifier">optional</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&amp;&gt;</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">&amp;</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">&amp;</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">&lt;</span><span class="identifier">T</span><span class="special">&amp;&gt;</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">&amp;</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">&amp;</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">&lt;</span><span class="keyword">int</span><span class="special">&amp;&gt;</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">&lt;</span><span class="keyword">int</span><span class="special">&amp;&gt;</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>
<h4>
<a name="boost_optional.rebinding_semantics_for_assignment_of_optional_references.h0"></a>
<span class="phrase"><a name="boost_optional.rebinding_semantics_for_assignment_of_optional_references.rationale"></a></span><a class="link" href="rebinding_semantics_for_assignment_of_optional_references.html#boost_optional.rebinding_semantics_for_assignment_of_optional_references.rationale">Rationale</a>
</h4>
<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">&lt;</span><span class="identifier">U</span><span class="special">&gt;</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">&amp;</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">&lt;</span><span class="identifier">T</span><span class="special">&amp;&gt;</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">&lt;</span><span class="keyword">int</span><span class="special">&amp;&gt;</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">&amp;</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">&lt;</span><span class="keyword">int</span><span class="special">&amp;&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&amp;&gt;</span></code>
would assign just like <code class="computeroutput"><span class="identifier">T</span><span class="special">&amp;</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">&lt;</span><span class="identifier">T</span><span class="special">&amp;&gt;</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 &#169; 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright &#169; 2014 Andrzej Krzemie&#324;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="../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="in_place_factories.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

File diff suppressed because it is too large Load Diff

View 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&#160;1.&#160;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: &lt;</span></code><a href="../../../../../../boost/optional/optional.hpp" target="_top">boost/optional/optional.hpp</a><span class="comment">&gt;</span>
<span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</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">&amp;</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">&amp;&amp;</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">&amp;</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">&amp;</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">&amp;&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">&gt;</span> <span class="keyword">explicit</span> <span class="identifier">optional</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">&gt;</span> <span class="keyword">explicit</span> <span class="identifier">optional</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">&gt;&amp;&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">InPlaceFactory</span><span class="special">&gt;</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">&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">TypedInPlaceFactory</span><span class="special">&gt;</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">&amp;</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">&amp;</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">&amp;</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">&amp;</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">&amp;</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span> <span class="identifier">T</span><span class="special">&amp;&amp;</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">&amp;</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">&amp;</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">&amp;</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&amp;&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">&gt;</span> <span class="identifier">optional</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">&gt;</span> <span class="identifier">optional</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">&gt;&amp;&amp;</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">&lt;</span><span class="keyword">class</span><span class="special">...</span> <span class="identifier">Args</span><span class="special">&gt;</span> <span class="keyword">void</span> <span class="identifier">emplace</span> <span class="special">(</span> <span class="identifier">Args</span><span class="special">...&amp;&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">InPlaceFactory</span><span class="special">&gt;</span> <span class="identifier">optional</span><span class="special">&amp;</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">&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">TypedInPlaceFactory</span><span class="special">&gt;</span> <span class="identifier">optional</span><span class="special">&amp;</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">&amp;</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">&amp;</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">&amp;</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">-&gt;()</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">-&gt;()</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">&amp;</span> <span class="keyword">operator</span> <span class="special">*()</span> <span class="keyword">const</span><span class="special">&amp;</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">&amp;</span> <span class="keyword">operator</span> <span class="special">*()</span> <span class="special">&amp;;</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">&amp;&amp;</span> <span class="keyword">operator</span> <span class="special">*()</span> <span class="special">&amp;&amp;;</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">&amp;</span> <span class="identifier">value</span><span class="special">()</span> <span class="keyword">const</span><span class="special">&amp;</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">&amp;</span> <span class="identifier">value</span><span class="special">()</span> <span class="special">&amp;</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">&amp;&amp;</span> <span class="identifier">value</span><span class="special">()</span> <span class="special">&amp;&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">&gt;</span> <span class="identifier">T</span> <span class="identifier">value_or</span><span class="special">(</span> <span class="identifier">U</span> <span class="special">&amp;&amp;</span> <span class="identifier">v</span> <span class="special">)</span> <span class="keyword">const</span><span class="special">&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">&gt;</span> <span class="identifier">T</span> <span class="identifier">value_or</span><span class="special">(</span> <span class="identifier">U</span> <span class="special">&amp;&amp;</span> <span class="identifier">v</span> <span class="special">)</span> <span class="special">&amp;&amp;</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">&amp;</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">&amp;</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">&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">inline</span> <span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&lt;</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">inline</span> <span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&gt;</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">inline</span> <span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&lt;=</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">inline</span> <span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&gt;=</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">inline</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">make_optional</span> <span class="special">(</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">inline</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">inline</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">get_optional_value_or</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">opt</span><span class="special">,</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">inline</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">get</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">inline</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">get</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="special">&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;*</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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="special">&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&amp;</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 &#169; 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright &#169; 2014 Andrzej Krzemie&#324;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>

View 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&#160;1.&#160;Boost.Optional">
<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;Boost.Optional">
<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">
<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="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">
<a name="boost_optional.synopsis"></a><a class="link" href="synopsis.html" title="Synopsis">Synopsis</a>
</h2></div></div></div>
<pre class="programlisting"><code class="computeroutput"><span class="comment">// In Header: &lt;</span></code><a href="../../../../../boost/optional/optional.hpp" target="_top">boost/optional/optional.hpp</a><span class="comment">&gt;</span>
<span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</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">&amp;</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">&amp;&amp;</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">&amp;</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">&amp;</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">&amp;&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">&gt;</span> <span class="keyword">explicit</span> <span class="identifier">optional</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">&gt;</span> <span class="keyword">explicit</span> <span class="identifier">optional</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">&gt;&amp;&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">InPlaceFactory</span><span class="special">&gt;</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">&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">TypedInPlaceFactory</span><span class="special">&gt;</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">&amp;</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">&amp;</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">&amp;</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">&amp;</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">&amp;</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span> <span class="identifier">T</span><span class="special">&amp;&amp;</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">&amp;</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">&amp;</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">&amp;</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&amp;&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">&gt;</span> <span class="identifier">optional</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">&gt;</span> <span class="identifier">optional</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">&gt;&amp;&amp;</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">&lt;</span><span class="keyword">class</span><span class="special">...</span> <span class="identifier">Args</span><span class="special">&gt;</span> <span class="keyword">void</span> <span class="identifier">emplace</span> <span class="special">(</span> <span class="identifier">Args</span><span class="special">...&amp;&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">InPlaceFactory</span><span class="special">&gt;</span> <span class="identifier">optional</span><span class="special">&amp;</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">&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">TypedInPlaceFactory</span><span class="special">&gt;</span> <span class="identifier">optional</span><span class="special">&amp;</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">&amp;</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">&amp;</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">&amp;</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">-&gt;()</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">-&gt;()</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">&amp;</span> <span class="keyword">operator</span> <span class="special">*()</span> <span class="keyword">const</span><span class="special">&amp;</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">&amp;</span> <span class="keyword">operator</span> <span class="special">*()</span> <span class="special">&amp;;</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">&amp;&amp;</span> <span class="keyword">operator</span> <span class="special">*()</span> <span class="special">&amp;&amp;;</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">&amp;</span> <span class="identifier">value</span><span class="special">()</span> <span class="keyword">const</span><span class="special">&amp;</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">&amp;</span> <span class="identifier">value</span><span class="special">()</span> <span class="special">&amp;</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">&amp;&amp;</span> <span class="identifier">value</span><span class="special">()</span> <span class="special">&amp;&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">&gt;</span> <span class="identifier">T</span> <span class="identifier">value_or</span><span class="special">(</span> <span class="identifier">U</span> <span class="special">&amp;&amp;</span> <span class="identifier">v</span> <span class="special">)</span> <span class="keyword">const</span><span class="special">&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">&gt;</span> <span class="identifier">T</span> <span class="identifier">value_or</span><span class="special">(</span> <span class="identifier">U</span> <span class="special">&amp;&amp;</span> <span class="identifier">v</span> <span class="special">)</span> <span class="special">&amp;&amp;</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">&amp;</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">&amp;</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">&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">inline</span> <span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&lt;</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">inline</span> <span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&gt;</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">inline</span> <span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&lt;=</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">inline</span> <span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&gt;=</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">inline</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">make_optional</span> <span class="special">(</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">inline</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">inline</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">get_optional_value_or</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">opt</span><span class="special">,</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">inline</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">get</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">inline</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">get</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="special">&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;*</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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="special">&amp;</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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&amp;</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 &#169; 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright &#169; 2014 Andrzej Krzemie&#324;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="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>

View 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&#160;1.&#160;Boost.Optional">
<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;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">&lt;</span><span class="identifier">point</span><span class="special">,</span><span class="keyword">bool</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">,</span><span class="keyword">bool</span><span class="special">&gt;</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">&lt;</span><span class="keyword">char</span><span class="special">,</span><span class="keyword">bool</span><span class="special">&gt;</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">&lt;</span><span class="identifier">point</span><span class="special">,</span><span class="keyword">bool</span><span class="special">&gt;</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">&lt;</span><span class="identifier">point</span><span class="special">,</span><span class="keyword">bool</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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>&#8212;where <code class="computeroutput"><span class="identifier">nil_t</span></code>
is some stateless POD&#8212;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">&lt;</span><span class="identifier">T</span><span class="special">,</span><span class="identifier">nil_t</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">,</span><span class="identifier">nil_t</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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&#8212;i.e.
possibly uninitialized&#8212;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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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 -&gt;</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&#8212;from the days of C APIs to modern C++ libraries&#8212;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">-&gt;</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">-&gt;</span></code> tell by themselves
&#8212;without any additional context&#8212; 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">-&gt;</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">&lt;</span><span class="identifier">X</span><span class="special">&gt;</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&lt;T&gt;
as a model of OptionalPointee</a>
</h6>
<p>
For value access operations <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;&gt;</span></code> uses operators <code class="computeroutput"><span class="special">*</span></code>
and <code class="computeroutput"><span class="special">-&gt;</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">&lt;&gt;</span></code> objects are not pointers. <span class="underline"><code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;&gt;</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">&lt;&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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 &#169; 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright &#169; 2014 Andrzej Krzemie&#324;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>

View File

@ -0,0 +1,108 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>A note about optional&lt;bool&gt;</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&lt;bool&gt;">A
note about optional&lt;bool&gt;</a>
</h3></div></div></div>
<p>
<code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="keyword">bool</span><span class="special">&gt;</span></code> should
be used with special caution and consideration.
</p>
<p>
First, it is functionally similar to a tristate boolean (false, maybe, true)
&#8212;such as <a href="../../../../../../doc/html/tribool.html" target="_top">boost::tribool</a>&#8212;
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">&lt;</span><span class="keyword">bool</span><span class="special">&gt;</span></code>.
It should be carefully considered if an <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="keyword">bool</span><span class="special">&gt;</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">&lt;&gt;</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">&lt;</span><span class="keyword">bool</span><span class="special">&gt;</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">&lt;</span><span class="keyword">bool</span><span class="special">&gt;</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">&lt;</span><span class="keyword">bool</span><span class="special">&gt;</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">&lt;&gt;</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 &#169; 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright &#169; 2014 Andrzej Krzemie&#324;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>

View 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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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>&#8212;where <code class="computeroutput"><span class="identifier">nil_t</span></code>
is some stateless POD&#8212;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">&lt;</span><span class="identifier">T</span><span class="special">,</span><span class="identifier">nil_t</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">,</span><span class="identifier">nil_t</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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&#8212;i.e.
possibly uninitialized&#8212;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 &#169; 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright &#169; 2014 Andrzej Krzemie&#324;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>

View File

@ -0,0 +1,187 @@
<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="../when_to_use_optional.html" title="When to use Optional">
</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="../when_to_use_optional.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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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 -&gt;</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&#8212;from the days of C APIs to modern C++ libraries&#8212;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">-&gt;</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">-&gt;</span></code> tell by themselves
&#8212;without any additional context&#8212; 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"><code class="computeroutput"><span class="identifier">OptionalPointee</span></code></a> concept. This
concept captures the syntactic usage of operators <code class="computeroutput"><span class="special">*</span></code>,
<code class="computeroutput"><span class="special">-&gt;</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">&lt;</span><span class="identifier">X</span><span class="special">&gt;</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"><code class="computeroutput"><span class="identifier">OptionalPointee</span></code></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&lt;T&gt;
as a model of OptionalPointee</a>
</h6>
<p>
For value access operations <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;&gt;</span></code> uses operators <code class="computeroutput"><span class="special">*</span></code>
and <code class="computeroutput"><span class="special">-&gt;</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">&lt;&gt;</span></code> objects are not pointers. <span class="underline"><code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;&gt;</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">&lt;&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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 &#169; 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright &#169; 2014 Andrzej Krzemie&#324;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="../when_to_use_optional.html"><img src="../../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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 &#169; 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright &#169; 2014 Andrzej Krzemie&#324;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>

View File

@ -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&lt;bool&gt;">
<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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="keyword">operator</span><span class="special">=</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="special">)</span></code>
</li>
<li class="listitem">
<code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</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">&amp;</span> <span class="special">)</span></code>
</li>
<li class="listitem">
<code class="computeroutput"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">&gt;</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="keyword">operator</span><span class="special">=</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="special">)</span></code>
</li>
<li class="listitem">
<code class="computeroutput"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">InPlaceFactory</span><span class="special">&gt;</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</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">&amp;</span>
<span class="special">)</span></code>
</li>
<li class="listitem">
<code class="computeroutput"><span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">TypedInPlaceFactory</span><span class="special">&gt;</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</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">&amp;</span>
<span class="special">)</span> </code>
</li>
<li class="listitem">
<code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;::</span><span class="identifier">reset</span><span class="special">(</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&amp;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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 &#169; 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright &#169; 2014 Andrzej Krzemie&#324;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>

View 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&lt;bool&gt;">
</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"><code class="computeroutput"><span class="identifier">CopyConstructible</span></code></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">&amp;</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">&amp;</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">&lt;</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">&gt;</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">&amp;</span> <span class="identifier">a0</span><span class="special">,</span> <span class="identifier">A1</span> <span class="keyword">const</span><span class="special">&amp;</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">&amp;</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">&amp;</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">(&amp;</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">&lt;</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">&gt;(</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">&lt;</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">&gt;</span>
<span class="identifier">InPlaceFactoryN</span> <span class="special">&lt;</span><span class="identifier">A0</span><span class="special">,...,</span><span class="identifier">AN</span><span class="special">&gt;</span> <span class="identifier">in_place</span> <span class="special">(</span> <span class="identifier">A0</span> <span class="keyword">const</span><span class="special">&amp;</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">&amp;</span> <span class="identifier">aN</span><span class="special">)</span> <span class="special">;</span>
<span class="keyword">template</span><span class="special">&lt;</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">&gt;</span>
<span class="identifier">TypedInPlaceFactoryN</span> <span class="special">&lt;</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">&gt;</span> <span class="identifier">in_place</span> <span class="special">(</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">a0</span><span class="special">,</span> <span class="identifier">A0</span> <span class="keyword">const</span><span class="special">&amp;</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">&amp;</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">&amp;</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">&lt;</span> <span class="keyword">class</span> <span class="identifier">InPlaceFactory</span> <span class="special">&gt;</span>
<span class="identifier">W</span> <span class="special">(</span> <span class="identifier">InPlaceFactory</span> <span class="keyword">const</span><span class="special">&amp;</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">&lt;</span><span class="identifier">X</span><span class="special">&gt;</span><span class="identifier">construct</span><span class="special">(&amp;</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 &#169; 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright &#169; 2014 Andrzej Krzemie&#324;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>

View 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&#160;1.&#160;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">&lt;</span><span class="identifier">point</span><span class="special">,</span><span class="keyword">bool</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">,</span><span class="keyword">bool</span><span class="special">&gt;</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">&lt;</span><span class="keyword">char</span><span class="special">,</span><span class="keyword">bool</span><span class="special">&gt;</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">&lt;</span><span class="identifier">point</span><span class="special">,</span><span class="keyword">bool</span><span class="special">&gt;</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">&lt;</span><span class="identifier">point</span><span class="special">,</span><span class="keyword">bool</span><span class="special">&gt;</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 &#169; 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright &#169; 2014 Andrzej Krzemie&#324;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>

View 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="relational_operators.html" title="Relational operators">
<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="relational_operators.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">&amp;</span></code>, and to some extent, <code class="computeroutput"><span class="identifier">T</span>
<span class="keyword">const</span><span class="special">&amp;</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">&lt;</span><span class="identifier">T</span><span class="special">&amp;&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&amp;&gt;</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">&amp;</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">&lt;</span><span class="keyword">const</span> <span class="keyword">int</span><span class="special">&amp;&gt;</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 &#169; 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright &#169; 2014 Andrzej Krzemie&#324;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="relational_operators.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>

View File

@ -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">&lt;</span><span class="identifier">T</span><span class="special">&amp;&gt;</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">&amp;</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">&lt;</span><span class="keyword">int</span><span class="special">&amp;&gt;</span> <span class="identifier">ora</span> <span class="special">;</span>
<span class="identifier">optional</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&amp;&gt;</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">&amp;</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">&amp;</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">&lt;</span><span class="identifier">T</span><span class="special">&amp;&gt;</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">&amp;</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">&amp;</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">&lt;</span><span class="keyword">int</span><span class="special">&amp;&gt;</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">&lt;</span><span class="keyword">int</span><span class="special">&amp;&gt;</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">&lt;</span><span class="identifier">U</span><span class="special">&gt;</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">&amp;</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">&lt;</span><span class="identifier">T</span><span class="special">&amp;&gt;</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">&lt;</span><span class="keyword">int</span><span class="special">&amp;&gt;</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">&amp;</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">&lt;</span><span class="keyword">int</span><span class="special">&amp;&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&amp;&gt;</span></code>
would assign just like <code class="computeroutput"><span class="identifier">T</span><span class="special">&amp;</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">&lt;</span><span class="identifier">T</span><span class="special">&amp;&gt;</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 &#169; 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright &#169; 2014 Andrzej Krzemie&#324;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>

View File

@ -0,0 +1,113 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Relational operators</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="when_to_use_optional.html" title="When to use Optional">
<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="when_to_use_optional.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_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.relational_operators"></a><a class="link" href="relational_operators.html" title="Relational operators">Relational
operators</a>
</h3></div></div></div>
<p>
Type <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code> is
<a href="http://www.sgi.com/tech/stl/EqualityComparable.html" target="_top"><code class="computeroutput"><span class="identifier">EqualityComparable</span></code></a> whenever <code class="computeroutput"><span class="identifier">T</span></code> is <a href="http://www.sgi.com/tech/stl/EqualityComparable.html" target="_top"><code class="computeroutput"><span class="identifier">EqualityComparable</span></code></a>. Two optional
objects containing a value compare in the same as their contained values.
The uninitialized state of <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>
is treated as a distinct value, equal to itself, and unequal to any value
of type <code class="computeroutput"><span class="identifier">T</span></code>:
</p>
<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">oN</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">boost</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">o0</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">o1</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">oN</span> <span class="special">!=</span> <span class="identifier">o0</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">oN</span><span class="special">);</span>
<span class="identifier">assert</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">assert</span><span class="special">(</span><span class="identifier">oN</span> <span class="special">==</span> <span class="identifier">oN</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">o0</span> <span class="special">==</span> <span class="identifier">o0</span><span class="special">);</span>
</pre>
<p>
The converting constructor from <code class="computeroutput"><span class="identifier">T</span></code>
as well as from <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">none</span></code> implies the existence and semantics
of the mixed comparison between <code class="computeroutput"><span class="identifier">T</span></code>
and <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code> as
well as between <code class="computeroutput"><span class="identifier">none_t</span></code> and
<code class="computeroutput"><span class="identifier">optionl</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>:
</p>
<pre class="programlisting"><span class="identifier">assert</span><span class="special">(</span><span class="identifier">oN</span> <span class="special">!=</span> <span class="number">0</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">boost</span><span class="special">::</span><span class="identifier">none</span><span class="special">);</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">o0</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">oN</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">assert</span><span class="special">(</span><span class="identifier">o0</span> <span class="special">==</span> <span class="number">0</span><span class="special">);</span>
</pre>
<p>
This mixed comparison has a practical interpretation, which is occasionally
useful:
</p>
<pre class="programlisting"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">choice</span> <span class="special">=</span> <span class="identifier">ask_user</span><span class="special">();</span>
<span class="keyword">if</span> <span class="special">(</span><span class="identifier">choice</span> <span class="special">==</span> <span class="number">2</span><span class="special">)</span>
<span class="identifier">start_procedure_2</span><span class="special">();</span>
</pre>
<p>
In the above example, the meaning of the comparison is 'user chose number
2'. If user chose nothing, he didn't choose number 2.
</p>
<p>
In case where <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code> is
compared to <code class="computeroutput"><span class="identifier">none</span></code>, it is not
required that <code class="computeroutput"><span class="identifier">T</span></code> be <a href="http://www.sgi.com/tech/stl/EqualityComparable.html" target="_top"><code class="computeroutput"><span class="identifier">EqualityComparable</span></code></a>.
</p>
<p>
In a similar manner, type <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>
is <a href="http://www.sgi.com/tech/stl/LessThanComparable.html" target="_top"><code class="computeroutput"><span class="identifier">LessThanComparable</span></code></a> whenever <code class="computeroutput"><span class="identifier">T</span></code> is <a href="http://www.sgi.com/tech/stl/LessThanComparable.html" target="_top"><code class="computeroutput"><span class="identifier">LessThanComparable</span></code></a>. The optional
object containing no value is compared less than any value of <code class="computeroutput"><span class="identifier">T</span></code>. To illustrate this, if the default ordering
of <code class="computeroutput"><span class="identifier">size_t</span></code> is {<code class="computeroutput"><span class="number">0</span></code>, <code class="computeroutput"><span class="number">1</span></code>,
<code class="computeroutput"><span class="number">2</span></code>, ...}, the default ordering
of <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">size_t</span><span class="special">&gt;</span></code>
is {<code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">none</span></code>, <code class="computeroutput"><span class="number">0</span></code>,
<code class="computeroutput"><span class="number">1</span></code>, <code class="computeroutput"><span class="number">2</span></code>,
...}. This order does not have a practical interpretation. The goal is to
have any semantically correct default ordering in order for <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code> to
be usable in ordered associative containers (wherever <code class="computeroutput"><span class="identifier">T</span></code>
is usable).
</p>
<p>
Mixed relational operators are the only case where the contained value of
an optional object can be inspected without the usage of value accessing
function (<code class="computeroutput"><span class="keyword">operator</span><span class="special">*</span></code>,
<code class="computeroutput"><span class="identifier">value</span></code>, <code class="computeroutput"><span class="identifier">value_or</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 &#169; 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright &#169; 2014 Andrzej Krzemie&#324;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="when_to_use_optional.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_references.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,109 @@
<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>
The very minimum requirement of <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>
is that <code class="computeroutput"><span class="identifier">T</span></code> is a complete type
and that it has a publicly accessible destructor. <code class="computeroutput"><span class="identifier">T</span></code>
doesn't even need to be constructible. You can use a very minimum interface:
</p>
<pre class="programlisting"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">o</span><span class="special">;</span> <span class="comment">// uninitialized</span>
<span class="identifier">assert</span><span class="special">(</span><span class="identifier">o</span> <span class="special">==</span> <span class="identifier">none</span><span class="special">);</span> <span class="comment">// check if initialized</span>
<span class="identifier">assert</span><span class="special">(!</span><span class="identifier">o</span><span class="special">);</span> <span class="comment">//</span>
<span class="identifier">o</span><span class="special">.</span><span class="identifier">value</span><span class="special">();</span> <span class="comment">// always throws</span>
</pre>
<p>
But this is practically useless. In order for <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>
to be able to do anything useful and offer all the spectrum of ways of accessing
the contained value, <code class="computeroutput"><span class="identifier">T</span></code> needs
to have at least one accessible constructor. 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 if your compiler does not support it,
resort to <a class="link" href="in_place_factories.html" title="In-Place Factories">In-Place
Factories</a>:
</p>
<pre class="programlisting"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">o</span><span class="special">;</span>
<span class="identifier">o</span><span class="special">.</span><span class="identifier">emplace</span><span class="special">(</span><span class="string">"T"</span><span class="special">,</span> <span class="string">"ctor"</span><span class="special">,</span> <span class="string">"params"</span><span class="special">);</span>
</pre>
<p>
If <code class="computeroutput"><span class="identifier">T</span></code> is <code class="computeroutput"><span class="identifier">MoveConstructible</span></code>,
<code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code> is
also <code class="computeroutput"><span class="identifier">MoveConstructible</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:
</p>
<pre class="programlisting"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">o</span> <span class="special">=</span> <span class="identifier">make_T</span><span class="special">();</span>
<span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">p</span> <span class="special">=</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;();</span>
</pre>
<p>
If <code class="computeroutput"><span class="identifier">T</span></code> is <a href="../../../../../utility/CopyConstructible.html" target="_top"><code class="computeroutput"><span class="identifier">CopyConstructible</span></code></a>, <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code> is
also <a href="../../../../../utility/CopyConstructible.html" target="_top"><code class="computeroutput"><span class="identifier">CopyConstructible</span></code></a>
and can be easily initialized from an lvalue of type <code class="computeroutput"><span class="identifier">T</span></code>:
</p>
<pre class="programlisting"><span class="identifier">T</span> <span class="identifier">v</span> <span class="special">=</span> <span class="identifier">make_T</span><span class="special">();</span>
<span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">o</span> <span class="special">=</span> <span class="identifier">v</span><span class="special">;</span>
<span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">p</span> <span class="special">=</span> <span class="identifier">o</span><span class="special">;</span>
</pre>
<p>
If <code class="computeroutput"><span class="identifier">T</span></code> is not <code class="computeroutput"><span class="identifier">MoveAssignable</span></code>, it is still possible to
reset the value of <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>
using function <code class="computeroutput"><span class="identifier">emplace</span><span class="special">()</span></code>:
</p>
<pre class="programlisting"><span class="identifier">optional</span><span class="special">&lt;</span><span class="keyword">const</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">o</span> <span class="special">=</span> <span class="identifier">make_T</span><span class="special">();</span>
<span class="identifier">o</span><span class="special">.</span><span class="identifier">emplace</span><span class="special">(</span><span class="identifier">make_another_T</span><span class="special">());</span>
</pre>
<p>
If <code class="computeroutput"><span class="identifier">T</span></code> is <code class="computeroutput"><span class="identifier">Moveable</span></code>
(both <code class="computeroutput"><span class="identifier">MoveConstructible</span></code> and
<code class="computeroutput"><span class="identifier">MoveAssignable</span></code>) then <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code> is
also <code class="computeroutput"><span class="identifier">Moveable</span></code> and additionally
can be constructed and assigned from an rvalue of type <code class="computeroutput"><span class="identifier">T</span></code>.
</p>
<p>
Similarly, if <code class="computeroutput"><span class="identifier">T</span></code> is <code class="computeroutput"><span class="identifier">Copyable</span></code> (both <a href="../../../../../utility/CopyConstructible.html" target="_top"><code class="computeroutput"><span class="identifier">CopyConstructible</span></code></a> and <code class="computeroutput"><span class="identifier">CopyAssignable</span></code>) then <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>
is also <code class="computeroutput"><span class="identifier">Copyable</span></code> and additionally
can be constructed and assigned 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="emphasis"><em>is not</em></span>
required to be <a href="http://www.sgi.com/tech/stl/DefaultConstructible.html" target="_top"><code class="computeroutput"><span class="identifier">DefaultConstructible</span></code></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 &#169; 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright &#169; 2014 Andrzej Krzemie&#324;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>

View File

@ -0,0 +1,142 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>When to use 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="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="relational_operators.html" title="Relational operators">
</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="relational_operators.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.when_to_use_optional"></a><a class="link" href="when_to_use_optional.html" title="When to use Optional">When to
use Optional</a>
</h3></div></div></div>
<p>
It is recommended to use <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>
in situations where there is exactly one, clear (to all parties) reason for
having no value of type <code class="computeroutput"><span class="identifier">T</span></code>,
and where the lack of value is as natural as having any regular value of
<code class="computeroutput"><span class="identifier">T</span></code>. One example of such situation
is asking the user in some GUI form to optionally specify some limit on an
<code class="computeroutput"><span class="keyword">int</span></code> value, but the user is allowed
to say 'I want the number not to be constrained by the maximum'. For another
example, consider a config parameter specifying how many threads the application
should launch. Leaving this parameter unspecified means that the application
should decide itself. For yet another example, consider a function returning
the index of the smallest element in a <code class="computeroutput"><span class="identifier">vector</span></code>.
We need to be prepared for the situation, where the <code class="computeroutput"><span class="identifier">vector</span></code>
is empty. Therefore a natural signature for such function would be:
</p>
<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">typename</span> <span class="identifier">T</span><span class="special">&gt;</span>
<span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">size_t</span><span class="special">&gt;</span> <span class="identifier">find_smallest_elem</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">std</span><span class="special">::</span><span class="identifier">vector</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">vec</span><span class="special">);</span>
</pre>
<p>
Here, having received an empty <code class="computeroutput"><span class="identifier">vec</span></code>
and having no <code class="computeroutput"><span class="identifier">size_t</span></code> to return
is not a <span class="emphasis"><em>failure</em></span> but a <span class="emphasis"><em>normal</em></span>,
albeit irregular, situation.
</p>
<p>
Another typical situation is to indicate that we do not have a value yet,
but we expect to have it later. This notion can be used in implementing solutions
like lazy initialization or a two-phase initialization.
</p>
<p>
<code class="computeroutput"><span class="identifier">optional</span></code> can be used to take
a non-<a href="http://www.sgi.com/tech/stl/DefaultConstructible.html" target="_top"><code class="computeroutput"><span class="identifier">DefaultConstructible</span></code></a> type <code class="computeroutput"><span class="identifier">T</span></code> and create a sibling type with a default
constructor. This is a way to add a <span class="emphasis"><em>null-state</em></span> to any
type that doesn't have it already.
</p>
<p>
Sometimes type <code class="computeroutput"><span class="identifier">T</span></code> already
provides a built-in null-state, but it may still be useful to wrap it into
<code class="computeroutput"><span class="identifier">optional</span></code>. Consider <code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code>.
When you read a piece of text from a GUI form or a DB table, it is hardly
ever that the empty string indicates anything else but a missing text. And
some data bases do not even distinguish between a null string entry and a
non-null string of length 0. Still, it may be practical to use <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">string</span><span class="special">&gt;</span></code>
to indicate in the returned type that we want to treat the empty string in
a special dedicated program path:
</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">optional</span><span class="special">&lt;</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span><span class="special">&gt;</span> <span class="identifier">name</span> <span class="special">=</span> <span class="identifier">ask_user_name</span><span class="special">())</span> <span class="special">{</span>
<span class="identifier">assert</span><span class="special">(*</span><span class="identifier">name</span> <span class="special">!=</span> <span class="string">""</span><span class="special">);</span>
<span class="identifier">logon_as</span><span class="special">(*</span><span class="identifier">name</span><span class="special">);</span>
<span class="special">}</span>
<span class="keyword">else</span> <span class="special">{</span>
<span class="identifier">skip_logon</span><span class="special">();</span>
<span class="special">}</span>
</pre>
<p>
In the example above, the assertion indicates that if we choose to use this
technique, we must translate the empty string state to an optional object
with no contained value (inside function <code class="computeroutput"><span class="identifier">ask_user_name</span></code>).
</p>
<h5>
<a name="boost_optional.tutorial.when_to_use_optional.h0"></a>
<span class="phrase"><a name="boost_optional.tutorial.when_to_use_optional.not_recommended_usages"></a></span><a class="link" href="when_to_use_optional.html#boost_optional.tutorial.when_to_use_optional.not_recommended_usages">Not
recommended usages</a>
</h5>
<p>
It is not recommended to use <code class="computeroutput"><span class="identifier">optional</span></code>
to indicate that we were not able to compute a value because of a <span class="emphasis"><em>failure</em></span>.
It is difficult to define what a failure is, but it usually has one common
characteristic: an associated information on the cause of the failure. This
can be the type and member data of an exception object, or an error code.
It is a bad design to signal a failure and not inform about the cause. If
you do not want to use exceptions, and do not like the fact that by returning
error codes you cannot return the computed value, you can use <a href="https://github.com/ptal/Boost.Expected" target="_top">Expected</a>
library. It is sort of <a href="../../../../../variant/index.html" target="_top">Boost.Variant</a>
that contains either a computed value or a reason why the computation failed.
</p>
<p>
Sometimes the distinction into what is a failure and what is a valid but
irregular result is blurry and depends on a particular usage and personal
preference. Consider a function that converts a <code class="computeroutput"><span class="identifier">string</span></code>
to an <code class="computeroutput"><span class="keyword">int</span></code>. Is it a failure that
you cannot convert? It might in some cases, but in other you may call it
exactly for the purpose of figuring out if a given <code class="computeroutput"><span class="identifier">string</span></code>
is convertible, and you are not even interested in the resulting value. Sometimes
when a conversion fails you may not consider it a failure, but you need to
know why it cannot be converted; for instance at which character it is determined
that the conversion is impossible. In this case returning <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span></code>
will not suffice. Finally, there is a use case where an input string that
does not represent an <code class="computeroutput"><span class="keyword">int</span></code> is
not a failure condition, but during the conversion we use resources whose
acquisition may fail. In that case the natural representation is to both
return <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span></code> and
signal failure:
</p>
<pre class="programlisting"><span class="identifier">optional</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</span> <span class="identifier">convert1</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">string</span><span class="special">&amp;</span> <span class="identifier">str</span><span class="special">);</span> <span class="comment">// throws</span>
<span class="identifier">expected</span><span class="special">&lt;</span><span class="identifier">ErrorT</span><span class="special">,</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;&gt;</span> <span class="identifier">convert2</span><span class="special">(</span><span class="keyword">const</span> <span class="identifier">string</span><span class="special">&amp;</span> <span class="identifier">str</span><span class="special">);</span> <span class="comment">// return either optional or error</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 &#169; 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright &#169; 2014 Andrzej Krzemie&#324;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="relational_operators.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View 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="Chapter&#160;1.&#160;Boost.Optional">
<link rel="up" href="../index.html" title="Chapter&#160;1.&#160;Boost.Optional">
<link rel="prev" href="exception_safety_guarantees.html" title="Exception Safety Guarantees">
<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>
<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="../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">
<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>
At the very minimum for <code class="computeroutput"><span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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 &#169; 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright &#169; 2014 Andrzej Krzemie&#324;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="../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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 293 B

BIN
doc/html/images/space.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 B

142
doc/html/index.html Normal file
View File

@ -0,0 +1,142 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<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="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>
<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="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>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>
<div><p class="copyright">Copyright &#169; 2003-2007 Fernando Luis Cacciola Carballal</p></div>
<div><p class="copyright">Copyright &#169; 2014 Andrzej Krzemie&#324;ski</p></div>
<div><div class="legalnotice">
<a name="optional.legal"></a><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></div>
</div></div>
<div class="toc">
<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/quick_start.html">Quick Start</a></span></dt>
<dd><dl>
<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/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/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/when_to_use_optional.html">When to
use Optional</a></span></dt>
<dt><span class="section"><a href="boost_optional/tutorial/relational_operators.html">Relational
operators</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&lt;bool&gt;</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/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.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/acknowledgements.html">Acknowledgements</a></span></dt>
</dl>
</div>
<div class="section">
<div class="titlepage"><div><div><h2 class="title" style="clear: both">
<a name="optional.introduction"></a><a class="link" href="index.html#optional.introduction" title="Introduction">Introduction</a>
</h2></div></div></div>
<p>
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>
<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 differently. 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">&lt;</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">&gt;</span>
<span class="identifier">boost</span><span class="special">::</span><span class="identifier">optional</span><span class="special">&lt;</span><span class="keyword">int</span><span class="special">&gt;</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">&lt;</span><span class="keyword">int</span><span class="special">&gt;</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: September 12, 2014 at 09:54:26 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/quick_start.html"><img src="../../../../doc/src/images/next.png" alt="Next"></a></div>
</body>
</html>

View File

@ -0,0 +1,187 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Reference</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="../boost_optional/tutorial/type_requirements.html" title="Type requirements">
<link rel="next" href="../boost_optional/reference/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="../boost_optional/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="../boost_optional/reference/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">
<a name="optional.reference"></a><a class="link" href="reference.html" title="Reference">Reference</a>
</h2></div></div></div>
<div class="toc"><dl class="toc">
<dt><span class="section"><a href="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></div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="boost_optional.reference.synopsis"></a><a class="link" href="reference.html#boost_optional.reference.synopsis" title="Synopsis">Synopsis</a>
</h3></div></div></div>
<pre class="programlisting"><code class="computeroutput"><span class="comment">// In Header: &lt;</span></code><a href="../../../../../boost/optional/optional.hpp" target="_top">boost/optional/optional.hpp</a><span class="comment">&gt;</span>
<span class="keyword">namespace</span> <span class="identifier">boost</span> <span class="special">{</span>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</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="../boost_optional/reference/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="../boost_optional/reference/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">&amp;</span> <span class="identifier">v</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/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">&amp;&amp;</span> <span class="identifier">v</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/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">&amp;</span> <span class="identifier">v</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/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">&amp;</span> <span class="identifier">rhs</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/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">&amp;&amp;</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="../boost_optional/reference/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">&lt;</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">&gt;</span> <span class="keyword">explicit</span> <span class="identifier">optional</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">rhs</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/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">&lt;</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">&gt;</span> <span class="keyword">explicit</span> <span class="identifier">optional</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">&gt;&amp;&amp;</span> <span class="identifier">rhs</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/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">&lt;</span><span class="keyword">class</span> <span class="identifier">InPlaceFactory</span><span class="special">&gt;</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">&amp;</span> <span class="identifier">f</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/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">&lt;</span><span class="keyword">class</span> <span class="identifier">TypedInPlaceFactory</span><span class="special">&gt;</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">&amp;</span> <span class="identifier">f</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/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">&amp;</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="../boost_optional/reference/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">&amp;</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">&amp;</span> <span class="identifier">v</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/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">&amp;</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span> <span class="identifier">T</span><span class="special">&amp;&amp;</span> <span class="identifier">v</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/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">&amp;</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">&amp;</span> <span class="identifier">rhs</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/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">&amp;</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&amp;&amp;</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="../boost_optional/reference/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">&lt;</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">&gt;</span> <span class="identifier">optional</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">rhs</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/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">&lt;</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">&gt;</span> <span class="identifier">optional</span><span class="special">&amp;</span> <span class="keyword">operator</span> <span class="special">=</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">U</span><span class="special">&gt;&amp;&amp;</span> <span class="identifier">rhs</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/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">&lt;</span><span class="keyword">class</span><span class="special">...</span> <span class="identifier">Args</span><span class="special">&gt;</span> <span class="keyword">void</span> <span class="identifier">emplace</span> <span class="special">(</span> <span class="identifier">Args</span><span class="special">...&amp;&amp;</span> <span class="identifier">args</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/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">&lt;</span><span class="keyword">class</span> <span class="identifier">InPlaceFactory</span><span class="special">&gt;</span> <span class="identifier">optional</span><span class="special">&amp;</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">&amp;</span> <span class="identifier">f</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/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">&lt;</span><span class="keyword">class</span> <span class="identifier">TypedInPlaceFactory</span><span class="special">&gt;</span> <span class="identifier">optional</span><span class="special">&amp;</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">&amp;</span> <span class="identifier">f</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/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">&amp;</span> <span class="identifier">get</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/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">&amp;</span> <span class="identifier">get</span><span class="special">()</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/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">-&gt;()</span> <span class="keyword">const</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/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">-&gt;()</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/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">&amp;</span> <span class="keyword">operator</span> <span class="special">*()</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/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">&amp;</span> <span class="keyword">operator</span> <span class="special">*()</span> <span class="special">&amp;</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/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">&amp;&amp;</span> <span class="keyword">operator</span> <span class="special">*()</span> <span class="special">&amp;&amp;</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/detailed_semantics.html#reference_optional_operator_asterisk_move"><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">&amp;</span> <span class="identifier">value</span><span class="special">()</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/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">&amp;</span> <span class="identifier">value</span><span class="special">()</span> <span class="special">&amp;</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/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">&amp;&amp;</span> <span class="identifier">value</span><span class="special">()</span> <span class="special">&amp;&amp;</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/detailed_semantics.html#reference_optional_value_move"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">&gt;</span> <span class="identifier">T</span> <span class="identifier">value_or</span><span class="special">(</span> <span class="identifier">U</span> <span class="special">&amp;&amp;</span> <span class="identifier">v</span> <span class="special">)</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/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">&lt;</span><span class="keyword">class</span> <span class="identifier">U</span><span class="special">&gt;</span> <span class="identifier">T</span> <span class="identifier">value_or</span><span class="special">(</span> <span class="identifier">U</span> <span class="special">&amp;&amp;</span> <span class="identifier">v</span> <span class="special">)</span> <span class="special">&amp;&amp;</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/detailed_semantics.html#reference_optional_value_or_move"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">F</span><span class="special">&gt;</span> <span class="identifier">T</span> <span class="identifier">value_or_eval</span><span class="special">(</span> <span class="identifier">F</span> <span class="identifier">f</span> <span class="special">)</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/detailed_semantics.html#reference_optional_value_or_call"><span class="inlinemediaobject"><img src="../images/callouts/R.png" alt="R"></span></a>
<span class="keyword">template</span><span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">F</span><span class="special">&gt;</span> <span class="identifier">T</span> <span class="identifier">value_or_eval</span><span class="special">(</span> <span class="identifier">F</span> <span class="identifier">f</span> <span class="special">)</span> <span class="special">&amp;&amp;</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/detailed_semantics.html#reference_optional_value_or_call_move"><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="../boost_optional/reference/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="../boost_optional/reference/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="keyword">noexcept</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/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="../boost_optional/reference/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="../boost_optional/reference/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">&amp;</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/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="../boost_optional/reference/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">&amp;</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">&amp;</span> <span class="keyword">default</span> <span class="special">)</span> <span class="keyword">const</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">y</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">y</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">inline</span> <span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&lt;</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">y</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">inline</span> <span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&gt;</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">y</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">inline</span> <span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&lt;=</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">y</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">inline</span> <span class="keyword">bool</span> <span class="keyword">operator</span> <span class="special">&gt;=</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">y</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</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="../boost_optional/reference/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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</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="../boost_optional/reference/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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">inline</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="identifier">make_optional</span> <span class="special">(</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">v</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">inline</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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">&amp;</span> <span class="identifier">v</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">inline</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">get_optional_value_or</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">opt</span><span class="special">,</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="keyword">default</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">inline</span> <span class="identifier">T</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">get</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">opt</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">inline</span> <span class="identifier">T</span><span class="special">&amp;</span> <span class="identifier">get</span> <span class="special">(</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="special">&amp;</span> <span class="identifier">opt</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</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="../boost_optional/reference/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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;*</span> <span class="identifier">opt</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="keyword">const</span><span class="special">&amp;</span> <span class="identifier">opt</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;</span> <span class="special">&amp;</span> <span class="identifier">opt</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/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">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">x</span><span class="special">,</span> <span class="identifier">optional</span><span class="special">&lt;</span><span class="identifier">T</span><span class="special">&gt;&amp;</span> <span class="identifier">y</span> <span class="special">)</span> <span class="special">;</span> <a class="link" href="../boost_optional/reference/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>
</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 &#169; 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright &#169; 2014 Andrzej Krzemie&#324;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="../boost_optional/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="../boost_optional/reference/detailed_semantics.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

View File

@ -0,0 +1,153 @@
<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="Boost.Optional">
<link rel="up" href="../index.html" title="Boost.Optional">
<link rel="prev" href="../boost_optional/quick_start/storage_in_containers.html" title="Storage in containers">
<link rel="next" href="../boost_optional/tutorial/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="../boost_optional/quick_start/storage_in_containers.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="../boost_optional/tutorial/design_overview.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="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="../boost_optional/tutorial/design_overview.html">Design Overview</a></span></dt>
<dt><span class="section"><a href="../boost_optional/tutorial/when_to_use_optional.html">When to
use Optional</a></span></dt>
<dt><span class="section"><a href="../boost_optional/tutorial/relational_operators.html">Relational
operators</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&lt;bool&gt;</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></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">&lt;</span><span class="identifier">point</span><span class="special">,</span><span class="keyword">bool</span><span class="special">&gt;</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">&lt;</span><span class="identifier">T</span><span class="special">,</span><span class="keyword">bool</span><span class="special">&gt;</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">&lt;</span><span class="keyword">char</span><span class="special">,</span><span class="keyword">bool</span><span class="special">&gt;</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">&lt;</span><span class="identifier">point</span><span class="special">,</span><span class="keyword">bool</span><span class="special">&gt;</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">&lt;</span><span class="identifier">point</span><span class="special">,</span><span class="keyword">bool</span><span class="special">&gt;</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>
<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 &#169; 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright &#169; 2014 Andrzej Krzemie&#324;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="../boost_optional/quick_start/storage_in_containers.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="../boost_optional/tutorial/design_overview.html"><img src="../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@ -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/lib/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

View File

@ -1,10 +1,10 @@
// 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
// 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)
//
// See http://www.boost.org/lib/optional for documentation.
// See http://www.boost.org/libs/optional for documentation.
//
// You are welcome to contact the author at:
// fernando_cacciola@hotmail.com
@ -16,14 +16,11 @@
// NOTE: Borland users have to include this header outside any precompiled headers
// (bcc<=5.64 cannot include instance data in a precompiled header)
// -- * To be verified, now that there's no unnamed namespace
namespace boost {
namespace {
none_t const none = ((none_t)0) ;
}
none_t const none = (static_cast<none_t>(0)) ;
} // namespace boost

View File

@ -4,7 +4,7 @@
// 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.
// See http://www.boost.org/libs/optional for documentation.
//
// You are welcome to contact the author at:
// fernando_cacciola@hotmail.com

View File

@ -4,7 +4,7 @@
// 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.
// See http://www.boost.org/libs/optional for documentation.
//
// You are welcome to contact the author at:
// fernando_cacciola@hotmail.com

View File

@ -0,0 +1,32 @@
// 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>
#if __cplusplus < 201103L
#include <string> // to make converting-ctor std::string(char const*) visible
#endif
namespace boost {
class bad_optional_access : public std::logic_error
{
public:
bad_optional_access()
: std::logic_error("Attempted to access the value of an uninitialized optional object.")
{}
};
} // namespace boost
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,21 +1,29 @@
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
// Copyright (C) 2003, 2008 Fernando Luis Cacciola Carballal.
//
// Use, modification, and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/lib/optional for documentation.
// See http://www.boost.org/libs/optional for documentation.
//
// You are welcome to contact the author at:
// fernando_cacciola@hotmail.com
//
// Revisions:
// 10 May 2008 (added swap related forward declaration) Niels Dekker
//
#ifndef BOOST_OPTIONAL_OPTIONAL_FWD_FLC_19NOV2002_HPP
#define BOOST_OPTIONAL_OPTIONAL_FWD_FLC_19NOV2002_HPP
namespace boost {
template<class T> class optional ;
template<class T> void swap ( optional<T>& , optional<T>& );
template<class T> struct optional_swap_should_use_default_constructor ;
} // namespace boost
#endif

View File

@ -0,0 +1,78 @@
// Copyright (C) 2005, 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_OPTIONAL_OPTIONAL_IO_FLC_19NOV2002_HPP
#define BOOST_OPTIONAL_OPTIONAL_IO_FLC_19NOV2002_HPP
#include <istream>
#include <ostream>
#include <boost/none.hpp>
#include <boost/assert.hpp>
#include "boost/optional/optional.hpp"
#include "boost/utility/value_init.hpp"
namespace boost
{
template<class CharType, class CharTrait, class T>
inline
std::basic_ostream<CharType, CharTrait>&
operator<<(std::basic_ostream<CharType, CharTrait>& out, optional<T> const& v)
{
if ( out.good() )
{
if ( !v )
out << "--" ;
else out << ' ' << *v ;
}
return out;
}
template<class CharType, class CharTrait, class T>
inline
std::basic_istream<CharType, CharTrait>&
operator>>(std::basic_istream<CharType, CharTrait>& in, optional<T>& v)
{
if (in.good())
{
int d = in.get();
if (d == ' ')
{
T x;
in >> x;
v = x;
}
else
{
if (d == '-')
{
d = in.get();
if (d == '-')
{
v = none;
return in;
}
}
in.setstate( std::ios::failbit );
}
}
return in;
}
} // namespace boost
#endif

View File

@ -1,9 +1,13 @@
<html>
<head>
<meta http-equiv="refresh" content="0; URL=doc/optional.html">
<meta http-equiv="refresh" content="0; URL=doc/html/index.html">
</head>
<body>
Automatic redirection failed, please go to
<a href="doc/optional.html">doc/optional.html</a>.
<a href="doc/html/index.html">doc/html/index.html</a>.&nbsp;<hr>
<p><EFBFBD> Copyright Beman Dawes, 2001</p>
<p>Distributed under the Boost Software License, Version 1.0. (See accompanying
file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy
at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</p>
</body>
</html>

15
meta/libraries.json Normal file
View File

@ -0,0 +1,15 @@
{
"key": "optional",
"name": "Optional",
"authors": [
"Fernando Cacciola"
],
"description": "Discriminated-union wrapper for optional values.",
"category": [
"Miscellaneous"
],
"maintainers": [
"Fernando Cacciola <fernando_cacciola -at- ciudad.com.ar>",
"Andrzej Krzemienski <akrzemi1 -at- gmail.com>"
]
}

View File

@ -1 +0,0 @@
bin

View File

@ -1,36 +0,0 @@
# Boost.Optional Library test Jamfile
#
# Copyright (C) 2003, Fernando Luis Cacciola Carballal.
#
# Use, modification, and distribution is subject to the Boost Software
# License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
#
subproject libs/optional/test ;
# bring in rules for testing
SEARCH on testing.jam = $(BOOST_BUILD_PATH) ;
include testing.jam ;
# Make tests run by default.
DEPENDS all : test ;
{
test-suite optional :
[ run optional_test.cpp ]
[ run optional_test_tie.cpp ]
[ run optional_test_ref.cpp ]
[ run optional_test_inplace.cpp ]
[ compile-fail optional_test_fail1.cpp ]
[ compile-fail optional_test_fail2.cpp ]
[ compile-fail optional_test_fail3a.cpp ]
[ compile-fail optional_test_fail3b.cpp ]
[ compile-fail optional_test_ref_fail1.cpp ]
[ compile-fail optional_test_ref_fail2.cpp ]
[ compile-fail optional_test_ref_fail3.cpp ]
[ compile-fail optional_test_ref_fail4.cpp ]
[ compile-fail optional_test_inplace_fail.cpp ]
[ compile-fail optional_test_inplace_fail2.cpp ]
;
}

View File

@ -20,15 +20,28 @@ import testing ;
[ run optional_test_tie.cpp ]
[ run optional_test_ref.cpp ]
[ run optional_test_inplace.cpp ]
[ 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 ]
[ run optional_test_minimum_requirements.cpp ]
[ compile-fail optional_test_fail1.cpp ]
[ compile-fail optional_test_fail2.cpp ]
[ compile-fail optional_test_fail3a.cpp ]
[ compile-fail optional_test_fail3b.cpp ]
[ compile-fail optional_test_ref_fail1.cpp ]
[ compile-fail optional_test_ref_fail2.cpp ]
[ compile-fail optional_test_ref_fail3.cpp ]
[ compile-fail optional_test_ref_fail4.cpp ]
[ compile-fail optional_test_inplace_fail.cpp ]
[ compile-fail optional_test_inplace_fail2.cpp ]
[ compile-fail optional_test_fail_implicit_bool_convert.cpp ]
[ compile-fail optional_test_fail_copying_a_moveable_type.cpp ]
[ compile-fail optional_test_fail_optional_rvalue_ref.cpp ]
[ compile-fail optional_test_ref_fail_init_from_Trefref.cpp ]
[ compile-fail optional_test_ref_fail_init_from_Urefref.cpp ]
[ compile-fail optional_test_ref_fail_assign_from_Trefref.cpp ]
[ compile-fail optional_test_ref_fail_assign_from_Urefref.cpp ]
[ compile-fail optional_test_fail_explicit_convert_in_value_or.cpp ]
[ compile-fail optional_test_fail_explicit_convert_in_value_or_call.cpp ]
;
}

View File

@ -1,4 +1,4 @@
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
// Copyright (C) 2003, 2008 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
@ -9,13 +9,20 @@
// You are welcome to contact the author at:
// fernando_cacciola@hotmail.com
//
// Revisions:
// 12 May 2008 (added more swap tests)
//
#include<iostream>
#include<stdexcept>
#include<string>
#define BOOST_ENABLE_ASSERT_HANDLER
#include "boost/optional.hpp"
#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
@ -115,12 +122,8 @@ void test_basics( T const* )
// Assignment
// T::operator= ( T const& x ) is used to copy new value.
set_pending_assign( ARG(T) ) ;
set_pending_copy ( ARG(T) ) ;
set_pending_dtor ( ARG(T) ) ;
oa = ob ;
check_is_not_pending_assign( ARG(T) ) ;
check_is_pending_copy ( ARG(T) ) ;
check_is_pending_dtor ( ARG(T) ) ;
check_initialized(oa);
check_value(oa,b,z);
@ -155,6 +158,95 @@ void test_basics( T const* )
ob.reset();
check_is_pending_dtor( ARG(T) ) ;
check_uninitialized(ob);
}
template<class T>
void test_conditional_ctor_and_get_valur_or ( T const* )
{
TRACE( std::endl << BOOST_CURRENT_FUNCTION );
T a(321);
T z(123);
optional<T> const cdef0(false,a);
optional<T> def0(false,a);
optional<T> def1 = boost::make_optional(false,a); // T is not within boost so ADL won't find make_optional unqualified
check_uninitialized(def0);
check_uninitialized(def1);
optional<T> const co0(true,a);
optional<T> o0(true,a);
optional<T> o1 = boost::make_optional(true,a); // T is not within boost so ADL won't find make_optional unqualified
check_initialized(o0);
check_initialized(o1);
check_value(o0,a,z);
check_value(o1,a,z);
T b = def0.get_value_or(z);
BOOST_CHECK( b == z ) ;
b = get_optional_value_or(def0,z);
BOOST_CHECK( b == z ) ;
b = o0.get_value_or(z);
BOOST_CHECK( b == a ) ;
b = get_optional_value_or(o0,z);
BOOST_CHECK( b == a ) ;
T const& crz = z ;
T& rz = z ;
T const& crzz = def0.get_value_or(crz);
BOOST_CHECK( crzz == crz ) ;
T& rzz = def0.get_value_or(rz);
BOOST_CHECK( rzz == rz ) ;
T const& crzzz = get_optional_value_or(cdef0,crz);
BOOST_CHECK( crzzz == crz ) ;
T& rzzz = get_optional_value_or(def0,rz);
BOOST_CHECK( rzzz == rz ) ;
T const& crb = o0.get_value_or(crz);
BOOST_CHECK( crb == a ) ;
T& rb = o0.get_value_or(rz);
BOOST_CHECK( rb == b ) ;
T const& crbb = get_optional_value_or(co0,crz);
BOOST_CHECK( crbb == b ) ;
T const& crbbb = get_optional_value_or(o0,crz);
BOOST_CHECK( crbbb == b ) ;
T& rbb = get_optional_value_or(o0,rz);
BOOST_CHECK( rbb == b ) ;
T& ra = a ;
optional<T&> defref(false,ra);
BOOST_CHECK(!defref);
optional<T&> ref(true,ra);
BOOST_CHECK(!!ref);
a = T(432);
BOOST_CHECK( *ref == a ) ;
T& r1 = defref.get_value_or(z);
BOOST_CHECK( r1 == z ) ;
T& r2 = ref.get_value_or(z);
BOOST_CHECK( r2 == a ) ;
}
//
@ -199,7 +291,7 @@ void test_uninitialized_access( T const* )
{
// This should throw because 'def' is uninitialized
T const& n = def.get() ;
unused_variable(n);
boost::ignore_unused(n);
passed = true ;
}
catch (...) {}
@ -210,7 +302,7 @@ void test_uninitialized_access( T const* )
{
// This should throw because 'def' is uninitialized
T const& n = *def ;
unused_variable(n);
boost::ignore_unused(n);
passed = true ;
}
catch (...) {}
@ -220,7 +312,7 @@ void test_uninitialized_access( T const* )
try
{
T v(5) ;
unused_variable(v);
boost::ignore_unused(v);
// This should throw because 'def' is uninitialized
*def = v ;
passed = true ;
@ -233,7 +325,7 @@ void test_uninitialized_access( T const* )
{
// This should throw because 'def' is uninitialized
T v = *(def.operator->()) ;
unused_variable(v);
boost::ignore_unused(v);
passed = true ;
}
catch (...) {}
@ -617,9 +709,9 @@ void test_relops( T const* )
{
TRACE( std::endl << BOOST_CURRENT_FUNCTION );
T v0(18);
T v1(19);
T v2(19);
T v0(0);
T v1(1);
T v2(1);
optional<T> def0 ;
optional<T> def1 ;
@ -664,6 +756,33 @@ void test_relops( T const* )
BOOST_CHECK ( opt1 > opt0 ) ;
BOOST_CHECK ( opt1 <= opt2 ) ;
BOOST_CHECK ( opt1 >= opt0 ) ;
// Compare against a value directly
BOOST_CHECK ( opt0 == v0 ) ;
BOOST_CHECK ( opt0 != v1 ) ;
BOOST_CHECK ( opt1 == v2 ) ;
BOOST_CHECK ( opt0 < v1 ) ;
BOOST_CHECK ( opt1 > v0 ) ;
BOOST_CHECK ( opt1 <= v2 ) ;
BOOST_CHECK ( opt1 >= v0 ) ;
BOOST_CHECK ( v0 != opt1 ) ;
BOOST_CHECK ( v1 == opt2 ) ;
BOOST_CHECK ( v0 < opt1 ) ;
BOOST_CHECK ( v1 > opt0 ) ;
BOOST_CHECK ( v1 <= opt2 ) ;
BOOST_CHECK ( v1 >= opt0 ) ;
BOOST_CHECK ( def0 != v0 ) ;
BOOST_CHECK ( !(def0 == v0) ) ;
BOOST_CHECK ( def0 < v0 ) ;
BOOST_CHECK ( !(def0 > v0) ) ;
BOOST_CHECK ( def0 <= v0 ) ;
BOOST_CHECK ( !(def0 >= v0) ) ;
BOOST_CHECK ( v0 != def0 ) ;
BOOST_CHECK ( !(v0 == def0) ) ;
BOOST_CHECK ( !(v0 < def0) ) ;
BOOST_CHECK ( v0 > def0 ) ;
BOOST_CHECK ( !(v0 <= def0) ) ;
BOOST_CHECK ( v0 >= opt0 ) ;
}
template<class T>
@ -680,6 +799,10 @@ void test_none( T const* )
BOOST_CHECK ( def0 == none ) ;
BOOST_CHECK ( non_def != none ) ;
BOOST_CHECK ( !def1 ) ;
BOOST_CHECK ( !(non_def < none) ) ;
BOOST_CHECK ( non_def > none ) ;
BOOST_CHECK ( !(non_def <= none) ) ;
BOOST_CHECK ( non_def >= none ) ;
non_def = none ;
BOOST_CHECK ( !non_def ) ;
@ -687,22 +810,52 @@ void test_none( T const* )
test_default_implicit_construction(T(1),none);
}
template<class T>
void test_arrow( T const* )
{
TRACE( std::endl << BOOST_CURRENT_FUNCTION );
T a(1234);
optional<T> oa(a) ;
optional<T> const coa(a) ;
BOOST_CHECK ( coa->V() == 1234 ) ;
oa->V() = 4321 ;
BOOST_CHECK ( a.V() = 1234 ) ;
BOOST_CHECK ( (*oa).V() = 4321 ) ;
}
void test_with_builtin_types()
{
TRACE( std::endl << BOOST_CURRENT_FUNCTION );
test_basics( ARG(double) );
test_conditional_ctor_and_get_valur_or( ARG(double) );
test_uninitialized_access( ARG(double) );
test_no_throwing_swap( ARG(double) );
test_relops( ARG(double) ) ;
test_none( ARG(double) ) ;
}
// MSVC < 11.0 doesn't destroy X when we call ptr->VBase::VBase.
// Make sure that we work around this bug.
struct VBase : virtual X
{
VBase(int v) : X(v) {}
// MSVC 8.0 doesn't generate this correctly...
VBase(const VBase& other) : X(static_cast<const X&>(other)) {}
};
void test_with_class_type()
{
TRACE( std::endl << BOOST_CURRENT_FUNCTION );
test_basics( ARG(X) );
test_basics( ARG(VBase) );
test_conditional_ctor_and_get_valur_or( ARG(X) );
test_direct_value_manip( ARG(X) );
test_uninitialized_access( ARG(X) );
test_throwing_direct_init( ARG(X) );
@ -715,6 +868,7 @@ void test_with_class_type()
test_throwing_swap( ARG(X) );
test_relops( ARG(X) ) ;
test_none( ARG(X) ) ;
test_arrow( ARG(X) ) ;
BOOST_CHECK ( X::count == 0 ) ;
}
@ -788,6 +942,364 @@ void test_conversions2()
BOOST_CHECK(*get(&opt1) == static_cast<double>(f));
}
namespace optional_swap_test
{
class default_ctor_exception : public std::exception {} ;
class copy_ctor_exception : public std::exception {} ;
class assignment_exception : public std::exception {} ;
//
// Base class for swap test classes. Its assignment should not be called, when swapping
// optional<T> objects. (The default std::swap would do so.)
//
class base_class_with_forbidden_assignment
{
public:
base_class_with_forbidden_assignment & operator=(const base_class_with_forbidden_assignment &)
{
BOOST_CHECK(!"The assignment should not be used while swapping!");
throw assignment_exception();
}
virtual ~base_class_with_forbidden_assignment() {}
};
//
// Class without default constructor
//
class class_without_default_ctor : public base_class_with_forbidden_assignment
{
public:
char data;
explicit class_without_default_ctor(char arg) : data(arg) {}
};
//
// Class whose default constructor should not be used by optional::swap!
//
class class_whose_default_ctor_should_not_be_used : public base_class_with_forbidden_assignment
{
public:
char data;
explicit class_whose_default_ctor_should_not_be_used(char arg) : data(arg) {}
class_whose_default_ctor_should_not_be_used()
{
BOOST_CHECK(!"This default constructor should not be used while swapping!");
throw default_ctor_exception();
}
};
//
// Class whose default constructor should be used by optional::swap.
// Its copy constructor should be avoided!
//
class class_whose_default_ctor_should_be_used : public base_class_with_forbidden_assignment
{
public:
char data;
explicit class_whose_default_ctor_should_be_used(char arg) : data(arg) { }
class_whose_default_ctor_should_be_used() : data('\0') { }
class_whose_default_ctor_should_be_used(const class_whose_default_ctor_should_be_used &)
{
BOOST_CHECK(!"This copy constructor should not be used while swapping!");
throw copy_ctor_exception();
}
};
//
// Class template whose default constructor should be used by optional::swap.
// Its copy constructor should be avoided!
//
template <class T>
class template_whose_default_ctor_should_be_used : public base_class_with_forbidden_assignment
{
public:
T data;
explicit template_whose_default_ctor_should_be_used(T arg) : data(arg) { }
template_whose_default_ctor_should_be_used() : data('\0') { }
template_whose_default_ctor_should_be_used(const template_whose_default_ctor_should_be_used &)
{
BOOST_CHECK(!"This copy constructor should not be used while swapping!");
throw copy_ctor_exception();
}
};
//
// Class whose explicit constructor should be used by optional::swap.
// Its other constructors should be avoided!
//
class class_whose_explicit_ctor_should_be_used : public base_class_with_forbidden_assignment
{
public:
char data;
explicit class_whose_explicit_ctor_should_be_used(char arg) : data(arg) { }
class_whose_explicit_ctor_should_be_used()
{
BOOST_CHECK(!"This default constructor should not be used while swapping!");
throw default_ctor_exception();
}
class_whose_explicit_ctor_should_be_used(const class_whose_explicit_ctor_should_be_used &)
{
BOOST_CHECK(!"This copy constructor should not be used while swapping!");
throw copy_ctor_exception();
}
};
void swap(class_whose_default_ctor_should_not_be_used & lhs, class_whose_default_ctor_should_not_be_used & rhs)
{
std::swap(lhs.data, rhs.data);
}
void swap(class_whose_default_ctor_should_be_used & lhs, class_whose_default_ctor_should_be_used & rhs)
{
std::swap(lhs.data, rhs.data);
}
void swap(class_without_default_ctor & lhs, class_without_default_ctor & rhs)
{
std::swap(lhs.data, rhs.data);
}
void swap(class_whose_explicit_ctor_should_be_used & lhs, class_whose_explicit_ctor_should_be_used & rhs)
{
std::swap(lhs.data, rhs.data);
}
template <class T>
void swap(template_whose_default_ctor_should_be_used<T> & lhs, template_whose_default_ctor_should_be_used<T> & rhs)
{
std::swap(lhs.data, rhs.data);
}
//
// optional<T>::swap should be customized when neither the copy constructor
// nor the default constructor of T are supposed to be used when swapping, e.g.,
// for the following type T = class_whose_explicit_ctor_should_be_used.
//
void swap(boost::optional<class_whose_explicit_ctor_should_be_used> & x, boost::optional<class_whose_explicit_ctor_should_be_used> & y)
{
bool hasX(x);
bool hasY(y);
if ( !hasX && !hasY )
return;
if( !hasX )
x = boost::in_place('\0');
else if ( !hasY )
y = boost::in_place('\0');
optional_swap_test::swap(*x,*y);
if( !hasX )
y = boost::none ;
else if( !hasY )
x = boost::none ;
}
} // End of namespace optional_swap_test.
namespace boost {
//
// Compile time tweaking on whether or not swap should use the default constructor:
//
template <> struct optional_swap_should_use_default_constructor<
optional_swap_test::class_whose_default_ctor_should_be_used> : mpl::true_ {} ;
template <> struct optional_swap_should_use_default_constructor<
optional_swap_test::class_whose_default_ctor_should_not_be_used> : mpl::false_ {} ;
template <class T> struct optional_swap_should_use_default_constructor<
optional_swap_test::template_whose_default_ctor_should_be_used<T> > : mpl::true_ {} ;
//
// Specialization of boost::swap:
//
template <>
void swap(optional<optional_swap_test::class_whose_explicit_ctor_should_be_used> & x, optional<optional_swap_test::class_whose_explicit_ctor_should_be_used> & y)
{
optional_swap_test::swap(x, y);
}
} // namespace boost
namespace std {
//
// Specializations of std::swap:
//
template <>
void swap(optional_swap_test::class_whose_default_ctor_should_be_used & x, optional_swap_test::class_whose_default_ctor_should_be_used & y)
{
optional_swap_test::swap(x, y);
}
template <>
void swap(optional_swap_test::class_whose_default_ctor_should_not_be_used & x, optional_swap_test::class_whose_default_ctor_should_not_be_used & y)
{
optional_swap_test::swap(x, y);
}
template <>
void swap(optional_swap_test::class_without_default_ctor & x, optional_swap_test::class_without_default_ctor & y)
{
optional_swap_test::swap(x, y);
}
template <>
void swap(optional_swap_test::class_whose_explicit_ctor_should_be_used & x, optional_swap_test::class_whose_explicit_ctor_should_be_used & y)
{
optional_swap_test::swap(x, y);
}
} // namespace std
//
// Tests whether the swap function works properly for optional<T>.
// Assumes that T has one data member, of type char.
// Returns true iff the test is passed.
//
template <class T>
bool test_swap_function( T const* )
{
const boost::unit_test::counter_t counter_before_test = boost::minimal_test::errors_counter();
try
{
optional<T> obj1;
optional<T> obj2('a');
// Self-swap should not have any effect.
swap(obj1, obj1);
swap(obj2, obj2);
BOOST_CHECK(!obj1);
BOOST_CHECK(!!obj2 && obj2->data == 'a');
// Call non-member swap.
swap(obj1, obj2);
// Test if obj1 and obj2 are really swapped.
BOOST_CHECK(!!obj1 && obj1->data == 'a');
BOOST_CHECK(!obj2);
// Call non-member swap one more time.
swap(obj1, obj2);
// Test if obj1 and obj2 are swapped back.
BOOST_CHECK(!obj1);
BOOST_CHECK(!!obj2 && obj2->data == 'a');
}
catch(const std::exception &)
{
// The swap function should not throw, for our test cases.
return false ;
}
return boost::minimal_test::errors_counter() == counter_before_test ;
}
//
// Tests whether the optional<T>::swap member function works properly.
// Assumes that T has one data member, of type char.
// Returns true iff the test is passed.
//
template <class T>
bool test_swap_member_function( T const* )
{
const boost::unit_test::counter_t counter_before_test = boost::minimal_test::errors_counter();
try
{
optional<T> obj1;
optional<T> obj2('a');
// Self-swap should not have any effect.
obj1.swap(obj1);
obj2.swap(obj2);
BOOST_CHECK(!obj1);
BOOST_CHECK(!!obj2 && obj2->data == 'a');
// Call member swap.
obj1.swap(obj2);
// Test if obj1 and obj2 are really swapped.
BOOST_CHECK(!!obj1 && obj1->data == 'a');
BOOST_CHECK(!obj2);
// Call member swap one more time.
obj1.swap(obj2);
// Test if obj1 and obj2 are swapped back.
BOOST_CHECK(!obj1);
BOOST_CHECK(!!obj2 && obj2->data == 'a');
}
catch(const std::exception &)
{
// The optional<T>::swap member function should not throw, for our test cases.
return false ;
}
return boost::minimal_test::errors_counter() == counter_before_test ;
}
//
// Tests compile time tweaking of swap, by means of
// optional_swap_should_use_default_constructor.
//
void test_swap_tweaking()
{
BOOST_CHECK( test_swap_function( ARG(optional_swap_test::class_without_default_ctor) ) );
BOOST_CHECK( test_swap_function( ARG(optional_swap_test::class_whose_default_ctor_should_be_used) ) );
BOOST_CHECK( test_swap_function( ARG(optional_swap_test::class_whose_default_ctor_should_not_be_used) ) );
BOOST_CHECK( test_swap_function( ARG(optional_swap_test::class_whose_explicit_ctor_should_be_used) ) );
BOOST_CHECK( test_swap_function( ARG(optional_swap_test::template_whose_default_ctor_should_be_used<char>) ) );
BOOST_CHECK( test_swap_member_function( ARG(optional_swap_test::class_without_default_ctor) ) );
BOOST_CHECK( test_swap_member_function( ARG(optional_swap_test::class_whose_default_ctor_should_be_used) ) );
BOOST_CHECK( test_swap_member_function( ARG(optional_swap_test::class_whose_default_ctor_should_not_be_used) ) );
BOOST_CHECK( test_swap_member_function( ARG(optional_swap_test::class_whose_explicit_ctor_should_be_used) ) );
BOOST_CHECK( test_swap_member_function( ARG(optional_swap_test::template_whose_default_ctor_should_be_used<char>) ) );
}
// Test for support for classes with overridden operator&
class CustomAddressOfClass
{
int n;
public:
CustomAddressOfClass() : n(0) {}
CustomAddressOfClass(CustomAddressOfClass const& that) : n(that.n) {}
explicit CustomAddressOfClass(int m) : n(m) {}
int* operator& () { return &n; }
bool operator== (CustomAddressOfClass const& that) const { return n == that.n; }
};
void test_custom_addressof_operator()
{
boost::optional< CustomAddressOfClass > o1(CustomAddressOfClass(10));
BOOST_CHECK(!!o1);
BOOST_CHECK(o1.get() == CustomAddressOfClass(10));
o1 = CustomAddressOfClass(20);
BOOST_CHECK(!!o1);
BOOST_CHECK(o1.get() == CustomAddressOfClass(20));
o1 = boost::none;
BOOST_CHECK(!o1);
}
int test_main( int, char* [] )
{
try
@ -797,6 +1309,8 @@ int test_main( int, char* [] )
test_no_implicit_conversions();
test_conversions1();
test_conversions2();
test_swap_tweaking();
test_custom_addressof_operator();
}
catch ( ... )
{

View File

@ -1,4 +1,5 @@
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
// 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
@ -9,6 +10,8 @@
// You are welcome to contact the author at:
// fernando_cacciola@hotmail.com
//
#include <boost/core/ignore_unused.hpp>
#ifdef ENABLE_TRACE
#define TRACE(msg) std::cout << msg << std::endl ;
#else
@ -37,7 +40,6 @@ void assertion_failed (char const * expr, char const * func, char const * file,
using boost::optional ;
template<class T> inline void unused_variable ( T ) {}
#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
using boost::swap ;

View File

@ -0,0 +1,189 @@
// 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&);
};
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);
}
#endif
#if (!defined BOOST_NO_CXX11_RVALUE_REFERENCES)
struct ThrowOnMove
{
ThrowOnMove(ThrowOnMove&&) { throw int(); }
ThrowOnMove(ThrowOnMove const&) { throw int(); }
ThrowOnMove(int){}
};
void test_no_moves_on_emplacement()
{
try {
optional<ThrowOnMove> o;
o.emplace(1);
BOOST_CHECK(o);
}
catch (...) {
BOOST_CHECK(false);
}
}
#endif
struct Thrower
{
Thrower(bool throw_) { if (throw_) throw int(); }
private:
Thrower(Thrower const&);
#if (!defined BOOST_NO_CXX11_RVALUE_REFERENCES)
Thrower(Thrower&&);
#endif
};
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_assignment_on_emplacement()
{
optional<const std::string> os;
BOOST_CHECK(!os);
os.emplace("wow");
BOOST_CHECK(os);
BOOST_CHECK(*os == "wow");
}
int test_main( int, char* [] )
{
try
{
#if (!defined BOOST_NO_CXX11_RVALUE_REFERENCES) && (!defined BOOST_NO_CXX11_VARIADIC_TEMPLATES)
test_emplace();
#endif
#if (!defined BOOST_NO_CXX11_RVALUE_REFERENCES)
test_no_moves_on_emplacement();
#endif
test_clear_on_throw();
test_no_assignment_on_emplacement();
}
catch ( ... )
{
BOOST_ERROR("Unexpected Exception caught!");
}
return 0;
}

View File

@ -0,0 +1,68 @@
// 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 SemiRegular // no operator==
{
private: void operator==(SemiRegular const&) const {}
private: void operator!=(SemiRegular const&) const {}
};
void test_equal_to_none_of_noncomparable_T()
{
optional<SemiRegular> i = SemiRegular();
optional<SemiRegular> o;
BOOST_CHECK(i != boost::none);
BOOST_CHECK(boost::none != i);
BOOST_CHECK(o == boost::none);
BOOST_CHECK(boost::none == o);
}
int test_main( int, char* [] )
{
try
{
test_equal_to_none_of_noncomparable_T();
}
catch ( ... )
{
BOOST_ERROR("Unexpected Exception caught!");
}
return 0;
}

View File

@ -13,14 +13,16 @@
#include "boost/optional.hpp"
struct A {} ;
struct B {} ;
//
// THIS TEST SHOULD FAIL TO COMPILE
//
void test_no_unsupported_conversion()
{
boost::optional<int> opt1(1) ;
boost::optional< std::string > opt2 ;
opt2 = opt1 ; // Cannot convert from "int" to "std::string"
boost::optional<A> opt1;
boost::optional<B> opt2;
opt2 = opt1 ; // Cannot convert from "A" to "B"
}

View File

@ -0,0 +1,36 @@
// 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
//
#include "boost/optional.hpp"
class MoveOnly
{
public:
int val;
MoveOnly(int v) : val(v) {}
MoveOnly(MoveOnly&& rhs) : val(rhs.val) { rhs.val = 0; }
void operator=(MoveOnly&& rhs) {val = rhs.val; rhs.val = 0; }
private:
MoveOnly(MoveOnly const&);
void operator=(MoveOnly const&);
};
//
// THIS TEST SHOULD FAIL TO COMPILE
//
void test_copying_optional_with_noncopyable_T()
{
boost::optional<MoveOnly> opt1 ;
boost::optional<MoveOnly> opt2(opt1) ;
}

View File

@ -0,0 +1,32 @@
// 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
//
#include "boost/optional.hpp"
//
// THIS TEST SHOULD FAIL TO COMPILE
//
struct U
{};
struct T
{
explicit T(U const&) {}
};
void test_implicit_conversion_to_bool()
{
boost::optional<T> opt;
opt.value_or(U());
}

View File

@ -0,0 +1,34 @@
// 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
//
#include "boost/optional.hpp"
//
// THIS TEST SHOULD FAIL TO COMPILE
//
struct U
{};
struct T
{
explicit T(U const&) {}
};
U get_U() { return U(); }
void test_verifying_the_implicit_conversion_to_bool()
{
boost::optional<T> opt;
opt.value_or_eval(get_U);
}

View 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/lib/optional for documentation.
//
// You are welcome to contact the author at:
// akrzemi1@gmail.com
//
#include "boost/optional.hpp"
//
// THIS TEST SHOULD FAIL TO COMPILE
//
#if !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS)
bool test_implicit_conversion_to_bool()
{
boost::optional<int> opt;
return opt;
}
#else
# error "Test skipped: this compiler does not support explicit conversion operators."
#endif

View File

@ -1,4 +1,4 @@
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
// 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
@ -7,17 +7,13 @@
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// fernando_cacciola@hotmail.com
// akrzemi1@gmail.com
//
#include "boost/optional.hpp"
//
// THIS TEST SHOULD FAIL TO COMPILE
//
void optional_reference__test_no_ptr_access()
{
boost::optional<int&> opt ;
opt.get_ptr();
}
boost::optional<int&&> oi;

92
test/optional_test_io.cpp Normal file
View File

@ -0,0 +1,92 @@
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
//
// Use, modification, and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// fernando_cacciola@hotmail.com
//
#include<stdexcept>
#include<string>
#include<sstream>
#define BOOST_ENABLE_ASSERT_HANDLER
#include "boost/optional/optional.hpp"
#include "boost/optional/optional_io.hpp"
#include "boost/none.hpp"
#include "boost/test/minimal.hpp"
#ifdef ENABLE_TRACE
#define TRACE(msg) std::cout << msg << std::endl ;
#else
#define TRACE(msg)
#endif
namespace boost {
void assertion_failed (char const * expr, char const * func, char const * file, long )
{
using std::string ;
string msg = string("Boost assertion failure for \"")
+ string(expr)
+ string("\" at file \"")
+ string(file)
+ string("\" function \"")
+ string(func)
+ string("\"") ;
TRACE(msg);
throw std::logic_error(msg);
}
}
using namespace std ;
using namespace boost ;
template<class Opt>
void test2( Opt o, Opt buff )
{
stringstream s ;
const int markv = 123 ;
int mark = 0 ;
s << o << " " << markv ;
s >> buff >> mark ;
BOOST_ASSERT( buff == o ) ;
BOOST_ASSERT( mark == markv ) ;
}
template<class T>
void test( T v, T w )
{
test2( make_optional(v), optional<T> ());
test2( make_optional(v), make_optional(w));
test2( optional<T> () , optional<T> ());
test2( optional<T> () , make_optional(w));
}
int test_main( int, char* [] )
{
try
{
test(1,2);
test(string("hello"),string("buffer"));
}
catch ( ... )
{
BOOST_ERROR("Unexpected Exception caught!");
}
return 0;
}

View File

@ -0,0 +1,104 @@
// 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"
class NonConstructible
{
private:
NonConstructible();
NonConstructible(NonConstructible const&);
#if (!defined BOOST_NO_CXX11_RVALUE_REFERENCES)
NonConstructible(NonConstructible &&);
#endif
};
void test_non_constructible()
{
optional<NonConstructible> o;
BOOST_CHECK(!o);
BOOST_CHECK(o == boost::none);
try {
o.value();
BOOST_CHECK(false);
}
catch(...) {
BOOST_CHECK(true);
}
}
class Guard
{
public:
explicit Guard(int) {}
private:
Guard();
Guard(Guard const&);
#if (!defined BOOST_NO_CXX11_RVALUE_REFERENCES)
Guard(Guard &&);
#endif
};
void test_guard()
{
optional<Guard> o;
o.emplace(1);
BOOST_CHECK(o);
}
void test_non_assignable()
{
optional<const std::string> o;
o.emplace("cat");
BOOST_CHECK(o);
BOOST_CHECK(*o == "cat");
}
int test_main( int, char* [] )
{
try
{
test_non_constructible();
test_guard();
test_non_assignable();
}
catch ( ... )
{
BOOST_ERROR("Unexpected Exception caught!");
}
return 0;
}

414
test/optional_test_move.cpp Normal file
View File

@ -0,0 +1,414 @@
// 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
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
enum State
{
sDefaultConstructed,
sValueCopyConstructed,
sValueMoveConstructed,
sCopyConstructed,
sMoveConstructed,
sMoveAssigned,
sCopyAssigned,
sValueCopyAssigned,
sValueMoveAssigned,
sMovedFrom,
sIntConstructed
};
struct OracleVal
{
State s;
int i;
OracleVal(int i = 0) : s(sIntConstructed), i(i) {}
};
struct Oracle
{
State s;
OracleVal val;
Oracle() : s(sDefaultConstructed) {}
Oracle(const OracleVal& v) : s(sValueCopyConstructed), val(v) {}
Oracle(OracleVal&& v) : s(sValueMoveConstructed), val(std::move(v)) {v.s = sMovedFrom;}
Oracle(const Oracle& o) : s(sCopyConstructed), val(o.val) {}
Oracle(Oracle&& o) : s(sMoveConstructed), val(std::move(o.val)) {o.s = sMovedFrom;}
Oracle& operator=(const OracleVal& v) { s = sValueCopyAssigned; val = v; return *this; }
Oracle& operator=(OracleVal&& v) { s = sValueMoveAssigned; val = std::move(v); v.s = sMovedFrom; return *this; }
Oracle& operator=(const Oracle& o) { s = sCopyAssigned; val = o.val; return *this; }
Oracle& operator=(Oracle&& o) { s = sMoveAssigned; val = std::move(o.val); o.s = sMovedFrom; return *this; }
};
bool operator==( Oracle const& a, Oracle const& b ) { return a.val.i == b.val.i; }
bool operator!=( Oracle const& a, Oracle const& b ) { return a.val.i != b.val.i; }
void test_move_ctor_from_U()
{
optional<Oracle> o1 ((OracleVal()));
BOOST_CHECK(o1);
BOOST_CHECK(o1->s == sValueMoveConstructed || o1->s == sMoveConstructed);
OracleVal v1;
optional<Oracle> o2 (v1);
BOOST_CHECK(o2);
BOOST_CHECK(o2->s == sValueCopyConstructed || o2->s == sCopyConstructed || o2->s == sMoveConstructed );
BOOST_CHECK(v1.s == sIntConstructed);
optional<Oracle> o3 (boost::move(v1));
BOOST_CHECK(o3);
BOOST_CHECK(o3->s == sValueMoveConstructed || o3->s == sMoveConstructed);
BOOST_CHECK(v1.s == sMovedFrom);
}
void test_move_ctor_form_T()
{
optional<Oracle> o1 ((Oracle()));
BOOST_CHECK(o1);
BOOST_CHECK(o1->s == sMoveConstructed);
Oracle v1;
optional<Oracle> o2 (v1);
BOOST_CHECK(o2);
BOOST_CHECK(o2->s == sCopyConstructed);
BOOST_CHECK(v1.s == sDefaultConstructed);
optional<Oracle> o3 (boost::move(v1));
BOOST_CHECK(o3);
BOOST_CHECK(o3->s == sMoveConstructed);
BOOST_CHECK(v1.s == sMovedFrom);
}
void test_move_ctor_from_optional_T()
{
optional<Oracle> o1;
optional<Oracle> o2(boost::move(o1));
BOOST_CHECK(!o1);
BOOST_CHECK(!o2);
optional<Oracle> o3((Oracle()));
optional<Oracle> o4(boost::move(o3));
BOOST_CHECK(o3);
BOOST_CHECK(o4);
BOOST_CHECK(o3->s == sMovedFrom);
BOOST_CHECK(o4->s == sMoveConstructed);
optional<Oracle> o5((optional<Oracle>()));
BOOST_CHECK(!o5);
optional<Oracle> o6((optional<Oracle>(Oracle())));
BOOST_CHECK(o6);
BOOST_CHECK(o6->s == sMoveConstructed);
optional<Oracle> o7(o6); // does copy ctor from non-const lvalue compile?
}
void test_move_assign_from_U()
{
optional<Oracle> o1 = boost::none; // test if additional ctors didn't break it
o1 = boost::none; // test if additional assignments didn't break it
o1 = OracleVal();
BOOST_CHECK(o1);
BOOST_CHECK(o1->s == sValueMoveConstructed);
o1 = OracleVal();
BOOST_CHECK(o1);
BOOST_CHECK(o1->s == sMoveAssigned);
OracleVal v1;
optional<Oracle> o2;
o2 = v1;
BOOST_CHECK(o2);
BOOST_CHECK(o2->s == sValueCopyConstructed);
BOOST_CHECK(v1.s == sIntConstructed);
o2 = v1;
BOOST_CHECK(o2);
BOOST_CHECK(o2->s == sCopyAssigned || o2->s == sMoveAssigned);
BOOST_CHECK(v1.s == sIntConstructed);
optional<Oracle> o3;
o3 = boost::move(v1);
BOOST_CHECK(o3);
BOOST_CHECK(o3->s == sValueMoveConstructed);
BOOST_CHECK(v1.s == sMovedFrom);
}
void test_move_assign_from_T()
{
optional<Oracle> o1;
o1 = Oracle();
BOOST_CHECK(o1);
BOOST_CHECK(o1->s == sMoveConstructed);
o1 = Oracle();
BOOST_CHECK(o1);
BOOST_CHECK(o1->s == sMoveAssigned);
Oracle v1;
optional<Oracle> o2;
o2 = v1;
BOOST_CHECK(o2);
BOOST_CHECK(o2->s == sCopyConstructed);
BOOST_CHECK(v1.s == sDefaultConstructed);
o2 = v1;
BOOST_CHECK(o2);
BOOST_CHECK(o2->s == sCopyAssigned);
BOOST_CHECK(v1.s == sDefaultConstructed);
optional<Oracle> o3;
o3 = boost::move(v1);
BOOST_CHECK(o3);
BOOST_CHECK(o3->s == sMoveConstructed);
BOOST_CHECK(v1.s == sMovedFrom);
}
void test_move_assign_from_optional_T()
{
optional<Oracle> o1;
optional<Oracle> o2;
o1 = optional<Oracle>();
BOOST_CHECK(!o1);
optional<Oracle> o3((Oracle()));
o1 = o3;
BOOST_CHECK(o3);
BOOST_CHECK(o3->s == sMoveConstructed);
BOOST_CHECK(o1);
BOOST_CHECK(o1->s == sCopyConstructed);
o2 = boost::move(o3);
BOOST_CHECK(o3);
BOOST_CHECK(o3->s == sMovedFrom);
BOOST_CHECK(o2);
BOOST_CHECK(o2->s == sMoveConstructed);
o2 = optional<Oracle>((Oracle()));
BOOST_CHECK(o2);
BOOST_CHECK(o2->s == sMoveAssigned);
}
class MoveOnly
{
public:
int val;
MoveOnly(int v) : val(v) {}
MoveOnly(MoveOnly&& rhs) : val(rhs.val) { rhs.val = 0; }
void operator=(MoveOnly&& rhs) {val = rhs.val; rhs.val = 0; }
private:
MoveOnly(MoveOnly const&);
void operator=(MoveOnly const&);
friend class MoveOnlyB;
};
void test_with_move_only()
{
optional<MoveOnly> o1;
optional<MoveOnly> o2((MoveOnly(1)));
BOOST_CHECK(o2);
BOOST_CHECK(o2->val == 1);
optional<MoveOnly> o3 (boost::move(o1));
BOOST_CHECK(!o3);
optional<MoveOnly> o4 (boost::move(o2));
BOOST_CHECK(o4);
BOOST_CHECK(o4->val == 1);
BOOST_CHECK(o2);
BOOST_CHECK(o2->val == 0);
o3 = boost::move(o4);
BOOST_CHECK(o3);
BOOST_CHECK(o3->val == 1);
BOOST_CHECK(o4);
BOOST_CHECK(o4->val == 0);
}
class MoveOnlyB
{
public:
int val;
MoveOnlyB(int v) : val(v) {}
MoveOnlyB(MoveOnlyB&& rhs) : val(rhs.val) { rhs.val = 0; }
void operator=(MoveOnlyB&& rhs) {val = rhs.val; rhs.val = 0; }
MoveOnlyB(MoveOnly&& rhs) : val(rhs.val) { rhs.val = 0; }
void operator=(MoveOnly&& rhs) {val = rhs.val; rhs.val = 0; }
private:
MoveOnlyB(MoveOnlyB const&);
void operator=(MoveOnlyB const&);
MoveOnlyB(MoveOnly const&);
void operator=(MoveOnly const&);
};
void test_move_assign_from_optional_U()
{
optional<MoveOnly> a((MoveOnly(2)));
optional<MoveOnlyB> b1;
b1 = boost::move(a);
BOOST_CHECK(b1);
BOOST_CHECK(b1->val == 2);
BOOST_CHECK(a);
BOOST_CHECK(a->val == 0);
b1 = MoveOnly(4);
BOOST_CHECK(b1);
BOOST_CHECK(b1->val == 4);
}
void test_move_ctor_from_optional_U()
{
optional<MoveOnly> a((MoveOnly(2)));
optional<MoveOnlyB> b1(boost::move(a));
BOOST_CHECK(b1);
BOOST_CHECK(b1->val == 2);
BOOST_CHECK(a);
BOOST_CHECK(a->val == 0);
optional<MoveOnlyB> b2(( optional<MoveOnly>(( MoveOnly(4) )) ));
BOOST_CHECK(b2);
BOOST_CHECK(b2->val == 4);
}
void test_swap()
{
optional<MoveOnly> a((MoveOnly(2)));
optional<MoveOnly> b((MoveOnly(3)));
swap(a, b);
BOOST_CHECK(a->val == 3);
BOOST_CHECK(b->val == 2);
}
void test_optional_ref_to_movables()
{
MoveOnly m(3);
optional<MoveOnly&> orm = m;
orm->val = 2;
BOOST_CHECK(m.val == 2);
optional<MoveOnly&> orm2 = orm;
orm2->val = 1;
BOOST_CHECK(m.val == 1);
BOOST_CHECK(orm->val == 1);
optional<MoveOnly&> orm3 = boost::move(orm);
orm3->val = 4;
BOOST_CHECK(m.val == 4);
BOOST_CHECK(orm->val == 4);
BOOST_CHECK(orm2->val == 4);
}
// these 4 classes have different noexcept signatures in move operations
struct NothrowBoth {
NothrowBoth(NothrowBoth&&) BOOST_NOEXCEPT_IF(true) {};
void operator=(NothrowBoth&&) BOOST_NOEXCEPT_IF(true) {};
};
struct NothrowCtor {
NothrowCtor(NothrowCtor&&) BOOST_NOEXCEPT_IF(true) {};
void operator=(NothrowCtor&&) BOOST_NOEXCEPT_IF(false) {};
};
struct NothrowAssign {
NothrowAssign(NothrowAssign&&) BOOST_NOEXCEPT_IF(false) {};
void operator=(NothrowAssign&&) BOOST_NOEXCEPT_IF(true) {};
};
struct NothrowNone {
NothrowNone(NothrowNone&&) BOOST_NOEXCEPT_IF(false) {};
void operator=(NothrowNone&&) BOOST_NOEXCEPT_IF(false) {};
};
#ifndef BOOST_NO_NOEXCEPT
void test_noexcept() // this is a compile-time test
{
BOOST_STATIC_ASSERT(::boost::is_nothrow_move_constructible<optional<NothrowBoth> >::value);
BOOST_STATIC_ASSERT(::boost::is_nothrow_move_assignable<optional<NothrowBoth> >::value);
BOOST_STATIC_ASSERT(BOOST_NOEXCEPT_EXPR(optional<NothrowBoth>()));
BOOST_STATIC_ASSERT(::boost::is_nothrow_move_constructible<optional<NothrowCtor> >::value);
BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_assignable<optional<NothrowCtor> >::value);
BOOST_STATIC_ASSERT(BOOST_NOEXCEPT_EXPR(optional<NothrowCtor>()));
BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_constructible<optional<NothrowAssign> >::value);
BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_assignable<optional<NothrowAssign> >::value);
BOOST_STATIC_ASSERT(BOOST_NOEXCEPT_EXPR(optional<NothrowAssign>()));
BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_constructible<optional<NothrowNone> >::value);
BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_assignable<optional<NothrowNone> >::value);
BOOST_STATIC_ASSERT(BOOST_NOEXCEPT_EXPR(optional<NothrowNone>()));
}
#endif // !defned BOOST_NO_NOEXCEPT
#endif
int test_main( int, char* [] )
{
try
{
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
test_move_ctor_from_U();
test_move_ctor_form_T();
test_move_ctor_from_optional_T();
test_move_ctor_from_optional_U();
test_move_assign_from_U();
test_move_assign_from_T();
test_move_assign_from_optional_T();
test_move_assign_from_optional_U();
test_with_move_only();
test_optional_ref_to_movables();
test_swap();
#endif
}
catch ( ... )
{
BOOST_ERROR("Unexpected Exception caught!");
}
return 0;
}

View File

@ -299,6 +299,23 @@ void test_none( T const* )
BOOST_CHECK ( !non_def ) ;
}
template<class T>
void test_arrow( T const* )
{
TRACE( std::endl << BOOST_CURRENT_FUNCTION );
T a(1234);
optional<T&> oa(a) ;
optional<T&> const coa(a) ;
BOOST_CHECK ( coa->V() == 1234 ) ;
oa->V() = 4321 ;
BOOST_CHECK ( a.V() = 4321 ) ;
}
void test_with_builtin_types()
{
TRACE( std::endl << BOOST_CURRENT_FUNCTION );
@ -315,16 +332,35 @@ void test_with_class_type()
test_basics( ARG(X) );
test_relops( ARG(X) ) ;
test_none ( ARG(X) ) ;
test_arrow ( ARG(X) ) ;
BOOST_CHECK ( X::count == 0 ) ;
}
void test_binding()
{
int i = 0 ;
optional<int&> ori1 = i ;
BOOST_CHECK( &(*ori1) == &i ) ;
optional<int&> ori2(i) ;
BOOST_CHECK( &(*ori2) == &i ) ;
int const ci = 0 ;
optional<int const&> orci1 = ci ;
BOOST_CHECK( &(*orci1) == &ci ) ;
optional<int const&> orci2(ci) ;
BOOST_CHECK( &(*orci2) == &ci ) ;
}
int test_main( int, char* [] )
{
try
{
test_with_class_type();
test_with_builtin_types();
test_binding();
}
catch ( ... )
{

View File

@ -0,0 +1,26 @@
// 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
//
#include "boost/optional.hpp"
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
//
// THIS TEST SHOULD FAIL TO COMPILE
//
void optional_reference__test_no_assign_from_Trefref()
{
boost::optional<const int&> opt;
opt = int(3);
}
#else
# error "Test skipped. This cannot be implemented w/o rvalue references."
#endif

View File

@ -0,0 +1,26 @@
// 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
//
#include "boost/optional.hpp"
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
//
// THIS TEST SHOULD FAIL TO COMPILE
//
void optional_reference__test_no_assign_from_Urefref()
{
boost::optional<const int&> opt;
opt = long(3);
}
#else
# error "Test skipped. This cannot be implemented w/o rvalue references."
#endif

View File

@ -0,0 +1,25 @@
// 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
//
#include "boost/optional.hpp"
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
//
// THIS TEST SHOULD FAIL TO COMPILE
//
void optional_reference__test_no_init_from_Trefref()
{
boost::optional<const int&> opt = int(3);
}
#else
# error "Test skipped. This cannot be implemented w/o rvalue references."
#endif

View File

@ -0,0 +1,25 @@
// 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
//
#include "boost/optional.hpp"
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
//
// THIS TEST SHOULD FAIL TO COMPILE
//
void optional_reference__test_no_init_from_Urefref()
{
boost::optional<const int&> opt = long(3);
}
#else
# error "Test skipped. This cannot be implemented w/o rvalue references."
#endif

View File

@ -0,0 +1,108 @@
// 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/test/minimal.hpp"
#include "optional_test_common.cpp"
const int global_i = 0;
class TestingReferenceBinding
{
public:
TestingReferenceBinding(const int& ii)
{
BOOST_CHECK(&ii == &global_i);
}
void operator=(const int& ii)
{
BOOST_CHECK(&ii == &global_i);
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
void operator=(int&&)
{
BOOST_CHECK(false);
}
#endif
};
class TestingReferenceBinding2 // same definition as above, I need a different type
{
public:
TestingReferenceBinding2(const int& ii)
{
BOOST_CHECK(&ii == &global_i);
}
void operator=(const int& ii)
{
BOOST_CHECK(&ii == &global_i);
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
void operator=(int&&)
{
BOOST_CHECK(false);
}
#endif
};
void test_broken_compiler()
{
// we are not testing boost::optional here, but the c++ compiler
// if this test fails, optional references will obviously fail too
const int& iref = global_i;
BOOST_CHECK(&iref == &global_i);
TestingReferenceBinding ttt = global_i;
ttt = global_i;
TestingReferenceBinding2 ttt2 = iref;
ttt2 = iref;
}
int test_main( int, char* [] )
{
try
{
test_broken_compiler();
}
catch ( ... )
{
BOOST_ERROR("Unexpected Exception caught!");
}
return 0;
}

View File

@ -0,0 +1,264 @@
// 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);
boost::ignore_unused(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);
}
struct FunM
{
int operator()() { return 5; }
};
struct FunC
{
int operator()() const { return 6; }
};
int funP ()
{
return 7;
}
int throw_()
{
throw int();
}
void test_function_value_or_eval()
{
optional<int> o1 = 1;
optional<int> oN;
FunM funM;
FunC funC;
BOOST_CHECK(o1.value_or_eval(funM) == 1);
BOOST_CHECK(oN.value_or_eval(funM) == 5);
BOOST_CHECK(o1.value_or_eval(FunM()) == 1);
BOOST_CHECK(oN.value_or_eval(FunM()) == 5);
BOOST_CHECK(o1.value_or_eval(funC) == 1);
BOOST_CHECK(oN.value_or_eval(funC) == 6);
BOOST_CHECK(o1.value_or_eval(FunC()) == 1);
BOOST_CHECK(oN.value_or_eval(FunC()) == 6);
BOOST_CHECK(o1.value_or_eval(funP) == 1);
BOOST_CHECK(oN.value_or_eval(funP) == 7);
#ifndef BOOST_NO_CXX11_LAMBDAS
BOOST_CHECK(o1.value_or_eval([](){return 8;}) == 1);
BOOST_CHECK(oN.value_or_eval([](){return 8;}) == 8);
#endif
try
{
BOOST_CHECK(o1.value_or_eval(throw_) == 1);
}
catch(...)
{
BOOST_CHECK(false);
}
try
{
BOOST_CHECK(oN.value_or_eval(throw_) == 1);
BOOST_CHECK(false);
}
catch(...)
{
BOOST_CHECK(true);
}
}
const optional<std::string> makeConstOptVal()
{
return std::string("something");
}
void test_const_move()
{
std::string s5 = *makeConstOptVal();
std::string s6 = makeConstOptVal().value();
boost::ignore_unused(s5);
boost::ignore_unused(s6);
}
#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);
}
MoveOnly moveOnlyDefault()
{
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));
MoveOnly m4 = makeMoveOnly().value_or_eval(moveOnlyDefault);
boost::ignore_unused(m1);
boost::ignore_unused(m2);
boost::ignore_unused(m3);
boost::ignore_unused(m4);
}
#endif // !defined BOOST_NO_CXX11_REF_QUALIFIERS
int test_main( int, char* [] )
{
try
{
test_function_value();
test_function_value_or();
test_function_value_or_eval();
test_const_move();
}
catch ( ... )
{
BOOST_ERROR("Unexpected Exception caught!");
}
return 0;
}