From 5182f7f30fad87023ae5e5a4e1f660fb513fb469 Mon Sep 17 00:00:00 2001 From: Andrzej Krzemienski Date: Sat, 24 Mar 2018 00:04:15 +0100 Subject: [PATCH 01/13] Added has_value() --- doc/27_ref_optional_synopsis.qbk | 4 ++ doc/28_ref_optional_semantics.qbk | 2 + doc/91_relnotes.qbk | 5 +++ doc/html/boost_optional/acknowledgements.html | 2 +- .../dependencies_and_portability.html | 2 +- ...emplace_operations_in_older_compilers.html | 2 +- .../optional_reference_binding.html | 2 +- doc/html/boost_optional/quick_start.html | 2 +- ...sing_unnecessary_default_construction.html | 2 +- .../optional_automatic_variables.html | 2 +- .../quick_start/optional_data_members.html | 2 +- .../quick_start/storage_in_containers.html | 2 +- ...ost_optional_bad_optional_access_hpp_.html | 2 +- .../detailed_semantics.html | 2 +- .../header__boost_optional_hpp_.html | 2 +- ...der__boost_optional_optional_fwd_hpp_.html | 2 +- .../detailed_semantics___free_functions.html | 2 +- ...ailed_semantics___optional_references.html | 5 ++- .../detailed_semantics___optional_values.html | 5 ++- .../header_optional_in_place_init.html | 2 +- .../header_optional_optional_refs.html | 4 +- .../header_optional_optional_values.html | 4 +- .../boost_optional/reference/io_header.html | 2 +- .../reference/io_header/io_semantics.html | 2 +- doc/html/boost_optional/relnotes.html | 41 +++++++++++++++---- .../tutorial/design_overview.html | 2 +- .../design_overview/the_interface.html | 2 +- .../design_overview/the_semantics.html | 2 +- .../tutorial/exception_safety_guarantees.html | 2 +- doc/html/boost_optional/tutorial/gotchas.html | 2 +- ...e_positive_with__wmaybe_uninitialized.html | 2 +- .../gotchas/mixed_relational_comparisons.html | 2 +- .../gotchas/moved_from__optional_.html | 2 +- .../tutorial/in_place_factories.html | 2 +- .../boost_optional/tutorial/io_operators.html | 2 +- .../tutorial/optional_references.html | 2 +- ...for_assignment_of_optional_references.html | 2 +- .../tutorial/performance_considerations.html | 15 +++---- .../tutorial/relational_operators.html | 2 +- .../tutorial/type_requirements.html | 2 +- .../tutorial/when_to_use_optional.html | 2 +- doc/html/index.html | 4 +- doc/html/optional/reference.html | 2 +- .../header__boost_optional_optional_hpp_.html | 2 +- doc/html/optional/tutorial.html | 2 +- .../detail/optional_reference_spec.hpp | 1 + include/boost/optional/optional.hpp | 4 +- test/optional_test.cpp | 2 +- ...st_common.cpp => optional_test_common.hpp} | 12 ++++++ 49 files changed, 119 insertions(+), 59 deletions(-) rename test/{optional_test_common.cpp => optional_test_common.hpp} (94%) diff --git a/doc/27_ref_optional_synopsis.qbk b/doc/27_ref_optional_synopsis.qbk index f93076e..1a6a849 100644 --- a/doc/27_ref_optional_synopsis.qbk +++ b/doc/27_ref_optional_synopsis.qbk @@ -182,6 +182,8 @@ They are empty, trivially copyable classes with disabled default constructor. T const* get_ptr() const ; ``[link reference_optional_get_ptr __GO_TO__]`` T* get_ptr() ; ``[link reference_optional_get_ptr __GO_TO__]`` + bool has_value() const noexcept ; ``[link reference_optional_operator_bool __GO_TO__]`` + explicit operator bool() const noexcept ; ``[link reference_optional_operator_bool __GO_TO__]`` bool operator!() const noexcept ; ``[link reference_optional_operator_not __GO_TO__]`` @@ -256,6 +258,8 @@ They are empty, trivially copyable classes with disabled default constructor. T* get_ptr() const noexcept ; ``[link reference_optional_ref_get_ptr __GO_TO__]`` + bool has_value() const noexcept ; ``[link reference_optional_ref_operator_bool __GO_TO__]`` + explicit operator bool() const noexcept ; ``[link reference_optional_ref_operator_bool __GO_TO__]`` bool operator!() const noexcept ; ``[link reference_optional_ref_operator_not __GO_TO__]`` diff --git a/doc/28_ref_optional_semantics.qbk b/doc/28_ref_optional_semantics.qbk index 7e2740c..8c1397f 100644 --- a/doc/28_ref_optional_semantics.qbk +++ b/doc/28_ref_optional_semantics.qbk @@ -754,6 +754,7 @@ __SPACE__ [#reference_optional_operator_bool] [: `explicit optional::operator bool() const noexcept ;`] +[: `bool optional::has_value() const noexcept ;`] * [*Returns:] `get_ptr() != 0`. * [*Notes:] On compilers that do not support explicit conversion operators this falls back to safe-bool idiom. @@ -1040,6 +1041,7 @@ __SPACE__ __SPACE__ [#reference_optional_ref_operator_bool] +[: `bool has_value() const noexcept;`] [: `optional::operator bool () const noexcept;`] * [*Returns:] `bool(ref)`. diff --git a/doc/91_relnotes.qbk b/doc/91_relnotes.qbk index d34861b..93e9799 100644 --- a/doc/91_relnotes.qbk +++ b/doc/91_relnotes.qbk @@ -11,6 +11,11 @@ [section:relnotes Release Notes] +[heading Boost Release 1.68] + +* Added member function `has_value()` for compatibility with `std::optional` ([@https://github.com/boostorg/optional/issues/52 issue #52]). + + [heading Boost Release 1.67] * Fixed [@https://github.com/boostorg/optional/issues/46 issue #46]. diff --git a/doc/html/boost_optional/acknowledgements.html b/doc/html/boost_optional/acknowledgements.html index 9d07002..f91a9f2 100644 --- a/doc/html/boost_optional/acknowledgements.html +++ b/doc/html/boost_optional/acknowledgements.html @@ -3,7 +3,7 @@ Acknowledgements - + diff --git a/doc/html/boost_optional/dependencies_and_portability.html b/doc/html/boost_optional/dependencies_and_portability.html index 24d0038..ca54b86 100644 --- a/doc/html/boost_optional/dependencies_and_portability.html +++ b/doc/html/boost_optional/dependencies_and_portability.html @@ -3,7 +3,7 @@ Dependencies and Portability - + diff --git a/doc/html/boost_optional/dependencies_and_portability/emplace_operations_in_older_compilers.html b/doc/html/boost_optional/dependencies_and_portability/emplace_operations_in_older_compilers.html index 2354e2e..afa139f 100644 --- a/doc/html/boost_optional/dependencies_and_portability/emplace_operations_in_older_compilers.html +++ b/doc/html/boost_optional/dependencies_and_portability/emplace_operations_in_older_compilers.html @@ -3,7 +3,7 @@ Emplace operations in older compilers - + diff --git a/doc/html/boost_optional/dependencies_and_portability/optional_reference_binding.html b/doc/html/boost_optional/dependencies_and_portability/optional_reference_binding.html index cffa160..9038cb2 100644 --- a/doc/html/boost_optional/dependencies_and_portability/optional_reference_binding.html +++ b/doc/html/boost_optional/dependencies_and_portability/optional_reference_binding.html @@ -3,7 +3,7 @@ Optional Reference Binding - + diff --git a/doc/html/boost_optional/quick_start.html b/doc/html/boost_optional/quick_start.html index d7dde63..18ea040 100644 --- a/doc/html/boost_optional/quick_start.html +++ b/doc/html/boost_optional/quick_start.html @@ -3,7 +3,7 @@ Quick Start - + diff --git a/doc/html/boost_optional/quick_start/bypassing_unnecessary_default_construction.html b/doc/html/boost_optional/quick_start/bypassing_unnecessary_default_construction.html index 7ccdb1b..2b38395 100644 --- a/doc/html/boost_optional/quick_start/bypassing_unnecessary_default_construction.html +++ b/doc/html/boost_optional/quick_start/bypassing_unnecessary_default_construction.html @@ -3,7 +3,7 @@ Bypassing unnecessary default construction - + diff --git a/doc/html/boost_optional/quick_start/optional_automatic_variables.html b/doc/html/boost_optional/quick_start/optional_automatic_variables.html index e135be1..b292f0a 100644 --- a/doc/html/boost_optional/quick_start/optional_automatic_variables.html +++ b/doc/html/boost_optional/quick_start/optional_automatic_variables.html @@ -3,7 +3,7 @@ Optional automatic variables - + diff --git a/doc/html/boost_optional/quick_start/optional_data_members.html b/doc/html/boost_optional/quick_start/optional_data_members.html index 93682f8..8402401 100644 --- a/doc/html/boost_optional/quick_start/optional_data_members.html +++ b/doc/html/boost_optional/quick_start/optional_data_members.html @@ -3,7 +3,7 @@ Optional data members - + diff --git a/doc/html/boost_optional/quick_start/storage_in_containers.html b/doc/html/boost_optional/quick_start/storage_in_containers.html index 4861178..36e3191 100644 --- a/doc/html/boost_optional/quick_start/storage_in_containers.html +++ b/doc/html/boost_optional/quick_start/storage_in_containers.html @@ -3,7 +3,7 @@ Storage in containers - + diff --git a/doc/html/boost_optional/reference/header__boost_optional_bad_optional_access_hpp_.html b/doc/html/boost_optional/reference/header__boost_optional_bad_optional_access_hpp_.html index 4269965..56d43fc 100644 --- a/doc/html/boost_optional/reference/header__boost_optional_bad_optional_access_hpp_.html +++ b/doc/html/boost_optional/reference/header__boost_optional_bad_optional_access_hpp_.html @@ -3,7 +3,7 @@ Header <boost/optional/bad_optional_access.hpp> - + diff --git a/doc/html/boost_optional/reference/header__boost_optional_bad_optional_access_hpp_/detailed_semantics.html b/doc/html/boost_optional/reference/header__boost_optional_bad_optional_access_hpp_/detailed_semantics.html index ba66f61..e85abc9 100644 --- a/doc/html/boost_optional/reference/header__boost_optional_bad_optional_access_hpp_/detailed_semantics.html +++ b/doc/html/boost_optional/reference/header__boost_optional_bad_optional_access_hpp_/detailed_semantics.html @@ -3,7 +3,7 @@ Detailed semantics - + diff --git a/doc/html/boost_optional/reference/header__boost_optional_hpp_.html b/doc/html/boost_optional/reference/header__boost_optional_hpp_.html index 2a81a82..f3a3649 100644 --- a/doc/html/boost_optional/reference/header__boost_optional_hpp_.html +++ b/doc/html/boost_optional/reference/header__boost_optional_hpp_.html @@ -3,7 +3,7 @@ Header <boost/optional.hpp> - + diff --git a/doc/html/boost_optional/reference/header__boost_optional_optional_fwd_hpp_.html b/doc/html/boost_optional/reference/header__boost_optional_optional_fwd_hpp_.html index f053e06..96f41a2 100644 --- a/doc/html/boost_optional/reference/header__boost_optional_optional_fwd_hpp_.html +++ b/doc/html/boost_optional/reference/header__boost_optional_optional_fwd_hpp_.html @@ -3,7 +3,7 @@ Header <boost/optional/optional_fwd.hpp> - + diff --git a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics___free_functions.html b/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics___free_functions.html index 1a48614..5b0780b 100644 --- a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics___free_functions.html +++ b/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics___free_functions.html @@ -3,7 +3,7 @@ Detailed Semantics - Free Functions - + diff --git a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics___optional_references.html b/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics___optional_references.html index ffe1733..4400216 100644 --- a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics___optional_references.html +++ b/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics___optional_references.html @@ -3,7 +3,7 @@ Detailed Semantics - Optional References - + @@ -422,6 +422,9 @@ space

+ bool has_value() const noexcept; +

+

optional<T&>::operator bool () const noexcept; diff --git a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics___optional_values.html b/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics___optional_values.html index b18c618..fd94a67 100644 --- a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics___optional_values.html +++ b/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics___optional_values.html @@ -3,7 +3,7 @@ Detailed Semantics - Optional Values - + @@ -1592,6 +1592,9 @@ const noexcept ;

+

+ bool optional<T>::has_value() const noexcept ; +

  • Returns: get_ptr() != 0. diff --git a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/header_optional_in_place_init.html b/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/header_optional_in_place_init.html index 8f1560e..d94a2b2 100644 --- a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/header_optional_in_place_init.html +++ b/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/header_optional_in_place_init.html @@ -3,7 +3,7 @@ Initialization tags - + diff --git a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/header_optional_optional_refs.html b/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/header_optional_optional_refs.html index ee518a4..f02cdb5 100644 --- a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/header_optional_optional_refs.html +++ b/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/header_optional_optional_refs.html @@ -3,7 +3,7 @@ Optional References - + @@ -75,6 +75,8 @@ T* get_ptr() const noexcept ; R + bool has_value() const noexcept ; R + explicit operator bool() const noexcept ; R bool operator!() const noexcept ; R diff --git a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/header_optional_optional_values.html b/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/header_optional_optional_values.html index 172da40..7780abd 100644 --- a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/header_optional_optional_values.html +++ b/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/header_optional_optional_values.html @@ -3,7 +3,7 @@ Optional Values - + @@ -108,6 +108,8 @@ T const* get_ptr() const ; R T* get_ptr() ; R + bool has_value() const noexcept ; R + explicit operator bool() const noexcept ; R bool operator!() const noexcept ; R diff --git a/doc/html/boost_optional/reference/io_header.html b/doc/html/boost_optional/reference/io_header.html index 675e598..78bcfd9 100644 --- a/doc/html/boost_optional/reference/io_header.html +++ b/doc/html/boost_optional/reference/io_header.html @@ -3,7 +3,7 @@ Header <boost/optional/optional_io.hpp> - + diff --git a/doc/html/boost_optional/reference/io_header/io_semantics.html b/doc/html/boost_optional/reference/io_header/io_semantics.html index d286c9d..13b7477 100644 --- a/doc/html/boost_optional/reference/io_header/io_semantics.html +++ b/doc/html/boost_optional/reference/io_header/io_semantics.html @@ -3,7 +3,7 @@ Detailed semantics - + diff --git a/doc/html/boost_optional/relnotes.html b/doc/html/boost_optional/relnotes.html index 9881def..7eb48e0 100644 --- a/doc/html/boost_optional/relnotes.html +++ b/doc/html/boost_optional/relnotes.html @@ -3,7 +3,7 @@ Release Notes - + @@ -28,6 +28,29 @@

+ Boost + Release 1.68 +

+
  • + Added member function has_value() for compatibility with std::optional (issue + #52). +
+

+ + Boost + Release 1.67 +

+
    +
  • + Fixed issue + #46. +
  • +
  • + Fixed -Wzero-as-null-pointer-constant warnings. +
  • +
+

+ Boost Release 1.66

@@ -45,7 +68,7 @@

- + Boost Release 1.63

@@ -69,7 +92,7 @@

- + Boost Release 1.62

@@ -77,7 +100,7 @@ Fixed Trac #12179.

- + Boost Release 1.61

@@ -120,7 +143,7 @@

- + Boost Release 1.60

@@ -131,7 +154,7 @@ #11203.

- + Boost Release 1.59

@@ -145,7 +168,7 @@

- + Boost Release 1.58

@@ -181,7 +204,7 @@

- + Boost Release 1.57

@@ -191,7 +214,7 @@ to fix C++03 compile error on logic_error("...")".

- + Boost Release 1.56

diff --git a/doc/html/boost_optional/tutorial/design_overview.html b/doc/html/boost_optional/tutorial/design_overview.html index 5d2a7a0..fe959b6 100644 --- a/doc/html/boost_optional/tutorial/design_overview.html +++ b/doc/html/boost_optional/tutorial/design_overview.html @@ -3,7 +3,7 @@ Design Overview - + diff --git a/doc/html/boost_optional/tutorial/design_overview/the_interface.html b/doc/html/boost_optional/tutorial/design_overview/the_interface.html index 6b860a7..5c7d153 100644 --- a/doc/html/boost_optional/tutorial/design_overview/the_interface.html +++ b/doc/html/boost_optional/tutorial/design_overview/the_interface.html @@ -3,7 +3,7 @@ The Interface - + diff --git a/doc/html/boost_optional/tutorial/design_overview/the_semantics.html b/doc/html/boost_optional/tutorial/design_overview/the_semantics.html index d84118a..cdbd9e6 100644 --- a/doc/html/boost_optional/tutorial/design_overview/the_semantics.html +++ b/doc/html/boost_optional/tutorial/design_overview/the_semantics.html @@ -3,7 +3,7 @@ The semantics - + diff --git a/doc/html/boost_optional/tutorial/exception_safety_guarantees.html b/doc/html/boost_optional/tutorial/exception_safety_guarantees.html index 925eca6..6d57a52 100644 --- a/doc/html/boost_optional/tutorial/exception_safety_guarantees.html +++ b/doc/html/boost_optional/tutorial/exception_safety_guarantees.html @@ -3,7 +3,7 @@ Exception Safety Guarantees - + diff --git a/doc/html/boost_optional/tutorial/gotchas.html b/doc/html/boost_optional/tutorial/gotchas.html index fab4d53..45c9435 100644 --- a/doc/html/boost_optional/tutorial/gotchas.html +++ b/doc/html/boost_optional/tutorial/gotchas.html @@ -3,7 +3,7 @@ Gotchas - + diff --git a/doc/html/boost_optional/tutorial/gotchas/false_positive_with__wmaybe_uninitialized.html b/doc/html/boost_optional/tutorial/gotchas/false_positive_with__wmaybe_uninitialized.html index 299b211..2352db7 100644 --- a/doc/html/boost_optional/tutorial/gotchas/false_positive_with__wmaybe_uninitialized.html +++ b/doc/html/boost_optional/tutorial/gotchas/false_positive_with__wmaybe_uninitialized.html @@ -3,7 +3,7 @@ False positive with -Wmaybe-uninitialized - + diff --git a/doc/html/boost_optional/tutorial/gotchas/mixed_relational_comparisons.html b/doc/html/boost_optional/tutorial/gotchas/mixed_relational_comparisons.html index a0c4eb0..187e457 100644 --- a/doc/html/boost_optional/tutorial/gotchas/mixed_relational_comparisons.html +++ b/doc/html/boost_optional/tutorial/gotchas/mixed_relational_comparisons.html @@ -3,7 +3,7 @@ Mixed relational comparisons - + diff --git a/doc/html/boost_optional/tutorial/gotchas/moved_from__optional_.html b/doc/html/boost_optional/tutorial/gotchas/moved_from__optional_.html index 2be1f77..0e1b772 100644 --- a/doc/html/boost_optional/tutorial/gotchas/moved_from__optional_.html +++ b/doc/html/boost_optional/tutorial/gotchas/moved_from__optional_.html @@ -3,7 +3,7 @@ Moved-from optional - + diff --git a/doc/html/boost_optional/tutorial/in_place_factories.html b/doc/html/boost_optional/tutorial/in_place_factories.html index 1f4e145..f00e5ed 100644 --- a/doc/html/boost_optional/tutorial/in_place_factories.html +++ b/doc/html/boost_optional/tutorial/in_place_factories.html @@ -3,7 +3,7 @@ In-Place Factories - + diff --git a/doc/html/boost_optional/tutorial/io_operators.html b/doc/html/boost_optional/tutorial/io_operators.html index 874f5ac..bbfc1f7 100644 --- a/doc/html/boost_optional/tutorial/io_operators.html +++ b/doc/html/boost_optional/tutorial/io_operators.html @@ -3,7 +3,7 @@ IO operators - + diff --git a/doc/html/boost_optional/tutorial/optional_references.html b/doc/html/boost_optional/tutorial/optional_references.html index 702733c..417ff36 100644 --- a/doc/html/boost_optional/tutorial/optional_references.html +++ b/doc/html/boost_optional/tutorial/optional_references.html @@ -3,7 +3,7 @@ Optional references - + diff --git a/doc/html/boost_optional/tutorial/optional_references/rebinding_semantics_for_assignment_of_optional_references.html b/doc/html/boost_optional/tutorial/optional_references/rebinding_semantics_for_assignment_of_optional_references.html index 219fd61..f12fb59 100644 --- a/doc/html/boost_optional/tutorial/optional_references/rebinding_semantics_for_assignment_of_optional_references.html +++ b/doc/html/boost_optional/tutorial/optional_references/rebinding_semantics_for_assignment_of_optional_references.html @@ -3,7 +3,7 @@ Rebinding semantics for assignment of optional references - + diff --git a/doc/html/boost_optional/tutorial/performance_considerations.html b/doc/html/boost_optional/tutorial/performance_considerations.html index f54e49e..6a6667d 100644 --- a/doc/html/boost_optional/tutorial/performance_considerations.html +++ b/doc/html/boost_optional/tutorial/performance_considerations.html @@ -3,7 +3,7 @@ Performance considerations - + @@ -56,12 +56,13 @@

We call it a direct storage. This makes optional<T> a trivially-copyable type for scalar Ts. - This only works for compilers that support defaulted functions. On compilers - without defaulted functions we still use the direct storage, but optional<T> is - no longer recognized as trivially-copyable. Apart from scalar types, we leave - the programmer a way of customizing her type, so that it is reconized by - optional as candidate for - optimized storage, by specializing type trait boost::opitonal_config::optional_uses_direct_storage_for: + This only works for compilers that support defaulted functions (including + defaulted move assignment and constructor). On compilers without defaulted + functions we still use the direct storage, but optional<T> + is no longer recognized as trivially-copyable. Apart from scalar types, we + leave the programmer a way of customizing her type, so that it is reconized + by optional as candidate + for optimized storage, by specializing type trait boost::opitonal_config::optional_uses_direct_storage_for:

struct X // not trivial
 {
diff --git a/doc/html/boost_optional/tutorial/relational_operators.html b/doc/html/boost_optional/tutorial/relational_operators.html
index 744120d..8aa9234 100644
--- a/doc/html/boost_optional/tutorial/relational_operators.html
+++ b/doc/html/boost_optional/tutorial/relational_operators.html
@@ -3,7 +3,7 @@
 
 Relational operators
 
-
+
 
 
 
diff --git a/doc/html/boost_optional/tutorial/type_requirements.html b/doc/html/boost_optional/tutorial/type_requirements.html
index 8a9eb7f..191f5fe 100644
--- a/doc/html/boost_optional/tutorial/type_requirements.html
+++ b/doc/html/boost_optional/tutorial/type_requirements.html
@@ -3,7 +3,7 @@
 
 Type requirements
 
-
+
 
 
 
diff --git a/doc/html/boost_optional/tutorial/when_to_use_optional.html b/doc/html/boost_optional/tutorial/when_to_use_optional.html
index 675bd3f..b56a8c0 100644
--- a/doc/html/boost_optional/tutorial/when_to_use_optional.html
+++ b/doc/html/boost_optional/tutorial/when_to_use_optional.html
@@ -3,7 +3,7 @@
 
 When to use Optional
 
-
+
 
 
 
diff --git a/doc/html/index.html b/doc/html/index.html
index 1429a21..b9ec32a 100644
--- a/doc/html/index.html
+++ b/doc/html/index.html
@@ -3,7 +3,7 @@
 
 Boost.Optional
 
-
+
 
 
 
@@ -146,7 +146,7 @@
 
 
 
-
+

Last revised: May 17, 2017 at 23:01:39 GMT

Last revised: March 23, 2018 at 23:01:17 GMT


diff --git a/doc/html/optional/reference.html b/doc/html/optional/reference.html index fe13339..da63269 100644 --- a/doc/html/optional/reference.html +++ b/doc/html/optional/reference.html @@ -3,7 +3,7 @@ Reference - + diff --git a/doc/html/optional/reference/header__boost_optional_optional_hpp_.html b/doc/html/optional/reference/header__boost_optional_optional_hpp_.html index 24626e3..fdfb029 100644 --- a/doc/html/optional/reference/header__boost_optional_optional_hpp_.html +++ b/doc/html/optional/reference/header__boost_optional_optional_hpp_.html @@ -3,7 +3,7 @@ Header <boost/optional/optional.hpp> - + diff --git a/doc/html/optional/tutorial.html b/doc/html/optional/tutorial.html index b3260b9..6d1122b 100644 --- a/doc/html/optional/tutorial.html +++ b/doc/html/optional/tutorial.html @@ -3,7 +3,7 @@ Tutorial - + diff --git a/include/boost/optional/detail/optional_reference_spec.hpp b/include/boost/optional/detail/optional_reference_spec.hpp index 012e91a..8e9974c 100644 --- a/include/boost/optional/detail/optional_reference_spec.hpp +++ b/include/boost/optional/detail/optional_reference_spec.hpp @@ -159,6 +159,7 @@ public: void reset() BOOST_NOEXCEPT { ptr_ = 0; } bool is_initialized() const BOOST_NOEXCEPT { return ptr_ != 0; } + bool has_value() const BOOST_NOEXCEPT { return ptr_ != 0; } #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES diff --git a/include/boost/optional/optional.hpp b/include/boost/optional/optional.hpp index 74ef49c..17c8f89 100644 --- a/include/boost/optional/optional.hpp +++ b/include/boost/optional/optional.hpp @@ -375,7 +375,7 @@ class optional_base : public optional_tag pointer_const_type get_ptr() const { return m_initialized ? get_ptr_impl() : 0 ; } pointer_type get_ptr() { return m_initialized ? get_ptr_impl() : 0 ; } - bool is_initialized() const { return m_initialized ; } + bool is_initialized() const BOOST_NOEXCEPT { return m_initialized ; } protected : @@ -1333,6 +1333,8 @@ class optional } #endif + bool has_value() const BOOST_NOEXCEPT { return this->is_initialized() ; } + bool operator!() const BOOST_NOEXCEPT { return !this->is_initialized() ; } BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT() diff --git a/test/optional_test.cpp b/test/optional_test.cpp index 017d4ff..3354430 100644 --- a/test/optional_test.cpp +++ b/test/optional_test.cpp @@ -32,7 +32,7 @@ #include "boost/core/lightweight_test.hpp" -#include "optional_test_common.cpp" +#include "optional_test_common.hpp" void test_implicit_construction ( optional opt, double v, double z ) { diff --git a/test/optional_test_common.cpp b/test/optional_test_common.hpp similarity index 94% rename from test/optional_test_common.cpp rename to test/optional_test_common.hpp index acb935c..943e646 100644 --- a/test/optional_test_common.cpp +++ b/test/optional_test_common.hpp @@ -194,6 +194,9 @@ inline void check_uninitialized_const ( optional const& opt ) BOOST_TEST( !opt ) ; BOOST_TEST( !get_pointer(opt) ) ; BOOST_TEST( !opt.get_ptr() ) ; + BOOST_TEST( !opt.has_value() ) ; + BOOST_TEST( !opt.is_initialized() ) ; + BOOST_TEST( opt == boost::none ) ; } template inline void check_uninitialized ( optional& opt ) @@ -204,6 +207,9 @@ inline void check_uninitialized ( optional& opt ) BOOST_TEST( !opt ) ; BOOST_TEST( !get_pointer(opt) ) ; BOOST_TEST( !opt.get_ptr() ) ; + BOOST_TEST( !opt.has_value() ) ; + BOOST_TEST( !opt.is_initialized() ) ; + BOOST_TEST( opt == boost::none ) ; check_uninitialized_const(opt); } @@ -220,6 +226,9 @@ inline void check_initialized_const ( optional const& opt ) BOOST_TEST ( !!opt ) ; BOOST_TEST ( get_pointer(opt) ) ; BOOST_TEST ( opt.get_ptr() ) ; + BOOST_TEST ( opt.has_value() ) ; + BOOST_TEST ( opt.is_initialized() ) ; + BOOST_TEST ( opt != boost::none ) ; } template @@ -234,6 +243,9 @@ inline void check_initialized ( optional& opt ) BOOST_TEST ( !!opt ) ; BOOST_TEST ( get_pointer(opt) ) ; BOOST_TEST ( opt.get_ptr() ) ; + BOOST_TEST ( opt.has_value() ) ; + BOOST_TEST ( opt.is_initialized() ) ; + BOOST_TEST ( opt != boost::none ) ; check_initialized_const(opt); } From e47a01700940654f3f9e461ac422f55a8d0ed0c8 Mon Sep 17 00:00:00 2001 From: Andrzej Krzemienski Date: Sat, 23 Jun 2018 18:27:14 +0200 Subject: [PATCH 02/13] added o.map() --- doc/00_optional.qbk | 2 +- doc/27_ref_optional_synopsis.qbk | 4 + doc/28_ref_optional_semantics.qbk | 19 +++ doc/91_relnotes.qbk | 1 + doc/html/boost_optional/acknowledgements.html | 3 +- .../dependencies_and_portability.html | 3 +- ...emplace_operations_in_older_compilers.html | 3 +- .../optional_reference_binding.html | 3 +- doc/html/boost_optional/quick_start.html | 3 +- ...sing_unnecessary_default_construction.html | 3 +- .../optional_automatic_variables.html | 3 +- .../quick_start/optional_data_members.html | 3 +- .../quick_start/storage_in_containers.html | 3 +- ...ost_optional_bad_optional_access_hpp_.html | 3 +- .../detailed_semantics.html | 3 +- .../header__boost_optional_hpp_.html | 3 +- ...der__boost_optional_optional_fwd_hpp_.html | 3 +- .../detailed_semantics___free_functions.html | 3 +- ...ailed_semantics___optional_references.html | 3 +- .../detailed_semantics___optional_values.html | 47 ++++- .../header_optional_in_place_init.html | 3 +- .../header_optional_optional_refs.html | 3 +- .../header_optional_optional_values.html | 7 +- .../boost_optional/reference/io_header.html | 3 +- .../reference/io_header/io_semantics.html | 3 +- doc/html/boost_optional/relnotes.html | 12 +- .../tutorial/design_overview.html | 3 +- .../design_overview/the_interface.html | 3 +- .../design_overview/the_semantics.html | 3 +- .../tutorial/exception_safety_guarantees.html | 3 +- doc/html/boost_optional/tutorial/gotchas.html | 3 +- ...e_positive_with__wmaybe_uninitialized.html | 3 +- .../gotchas/mixed_relational_comparisons.html | 3 +- .../gotchas/moved_from__optional_.html | 3 +- .../tutorial/in_place_factories.html | 3 +- .../boost_optional/tutorial/io_operators.html | 3 +- .../tutorial/optional_references.html | 3 +- ...for_assignment_of_optional_references.html | 3 +- .../tutorial/performance_considerations.html | 3 +- .../tutorial/relational_operators.html | 3 +- .../tutorial/type_requirements.html | 3 +- .../tutorial/when_to_use_optional.html | 3 +- doc/html/index.html | 5 +- doc/html/optional/reference.html | 3 +- .../header__boost_optional_optional_hpp_.html | 3 +- doc/html/optional/tutorial.html | 3 +- .../detail/optional_reference_spec.hpp | 11 +- include/boost/optional/optional.hpp | 51 +++++- test/Jamfile.v2 | 1 + test/optional_test_map.cpp | 160 ++++++++++++++++++ 50 files changed, 343 insertions(+), 91 deletions(-) create mode 100644 test/optional_test_map.cpp diff --git a/doc/00_optional.qbk b/doc/00_optional.qbk index 02e21f4..00b6096 100644 --- a/doc/00_optional.qbk +++ b/doc/00_optional.qbk @@ -2,7 +2,7 @@ [quickbook 1.4] [authors [Cacciola Carballal, Fernando Luis]] [copyright 2003-2007 Fernando Luis Cacciola Carballal] - [copyright 2014-2017 Andrzej Krzemieński] + [copyright 2014-2018 Andrzej Krzemieński] [category miscellaneous] [id optional] [dirname optional] diff --git a/doc/27_ref_optional_synopsis.qbk b/doc/27_ref_optional_synopsis.qbk index 1a6a849..8454218 100644 --- a/doc/27_ref_optional_synopsis.qbk +++ b/doc/27_ref_optional_synopsis.qbk @@ -179,6 +179,10 @@ They are empty, trivially copyable classes with disabled default constructor. template T value_or_eval( F f ) const& ; ``[link reference_optional_value_or_call __GO_TO__]`` template T value_or_eval( F f ) && ; ``[link reference_optional_value_or_call_move __GO_TO__]`` + template auto map( F f ) const& -> ``['see below]``; ``[link reference_optional_map __GO_TO__]`` + template auto map( F f ) & -> ``['see below]``; ``[link reference_optional_map __GO_TO__]`` + template auto map( F f ) && -> ``['see below]``; ``[link reference_optional_map_move __GO_TO__]`` + T const* get_ptr() const ; ``[link reference_optional_get_ptr __GO_TO__]`` T* get_ptr() ; ``[link reference_optional_get_ptr __GO_TO__]`` diff --git a/doc/28_ref_optional_semantics.qbk b/doc/28_ref_optional_semantics.qbk index 8c1397f..320da2d 100644 --- a/doc/28_ref_optional_semantics.qbk +++ b/doc/28_ref_optional_semantics.qbk @@ -685,6 +685,25 @@ __SPACE__ __SPACE__ +[#reference_optional_map] + +[: `template auto optional::map(F f) const& -> ``['see below]`` ;`] +[: `template auto optional::map(F f) & -> ``['see below]`` ;`] + +* [*Effects:] `if (*this) return f(**this); else return none;` +* [*Notes:] The return type of these overloads is `optional`. On compilers that do not support ref-qualifiers on member functions, these two (as well as the next one) overloads are replaced with good old const and non-const overloads. + +__SPACE__ + +[#reference_optional_map_move] + +[: `template auto optional::map(F f) && -> ``['see below]`` ;`] + +* [*Effects:] `if (*this) return f(std::move(**this)); else return none;` +* [*Notes:] The return type of this overload is `optional`. + +__SPACE__ + [#reference_optional_get_value_or_value] [: `T const& optional::get_value_or( T const& default) const ;`] diff --git a/doc/91_relnotes.qbk b/doc/91_relnotes.qbk index 93e9799..79bb200 100644 --- a/doc/91_relnotes.qbk +++ b/doc/91_relnotes.qbk @@ -14,6 +14,7 @@ [heading Boost Release 1.68] * Added member function `has_value()` for compatibility with `std::optional` ([@https://github.com/boostorg/optional/issues/52 issue #52]). +* Added member function `map()` for transforming `optional` into `optional` using a function of type `U(T)`. [heading Boost Release 1.67] diff --git a/doc/html/boost_optional/acknowledgements.html b/doc/html/boost_optional/acknowledgements.html index f91a9f2..c6f9f2f 100644 --- a/doc/html/boost_optional/acknowledgements.html +++ b/doc/html/boost_optional/acknowledgements.html @@ -116,8 +116,7 @@ -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+

+ space +

+

+ template<class F> auto optional<T>::map(F f) const& -> + ['see below] ; +

+

+ template<class F> auto optional<T>::map(F f) & -> ['see below] + ; +

+
    +
  • + Effects: if + (*this) return f(**this); else return + none; +
  • +
  • + Notes: The return type of these overloads + is optional<decltype(f(**this)>. + On compilers that do not support ref-qualifiers on member functions, + these two (as well as the next one) overloads are replaced with good + old const and non-const overloads. +
  • +
+

+ space +

+

+ template<class F> auto optional<T>::map(F f) && + -> ['see below] + ; +

+
    +
  • + Effects: if + (*this) return f(std::move(**this)); else return + none; +
  • +
  • + Notes: The return type of this overload + is optional<decltype(f(istd::move(**this))>. +
  • +

space

@@ -1654,8 +1698,7 @@ -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+

Distributed under the Boost Software License, Version 1.0. (See accompanying @@ -146,7 +145,7 @@

- +

Last revised: March 23, 2018 at 23:01:17 GMT

Last revised: June 23, 2018 at 16:25:31 GMT


diff --git a/doc/html/optional/reference.html b/doc/html/optional/reference.html index da63269..d3b0ab7 100644 --- a/doc/html/optional/reference.html +++ b/doc/html/optional/reference.html @@ -75,8 +75,7 @@ -
-
-
+

+ space +

+

+ template<class F> auto optional<T&>::map( F f ) const -> see below; +

+
    +
  • + Effects: Equivalent to if (*this) return f(**this); else return none;. +
  • +
  • + Remarks: The return type of this function + is optional<decltype(f(**this))>. +
  • +

space

diff --git a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics___optional_values.html b/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics___optional_values.html index 46fe0a8..127df4c 100644 --- a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics___optional_values.html +++ b/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics___optional_values.html @@ -1476,10 +1476,10 @@

template<class F> auto optional<T>::map(F f) const& -> - ['see below] ; + see below ;

- template<class F> auto optional<T>::map(F f) & -> ['see below] + template<class F> auto optional<T>::map(F f) & -> see below ;

    @@ -1490,7 +1490,7 @@
  • Notes: The return type of these overloads - is optional<decltype(f(**this)>. + is optional<decltype(f(**this))>. On compilers that do not support ref-qualifiers on member functions, these two (as well as the next one) overloads are replaced with good old const and non-const overloads. @@ -1501,7 +1501,7 @@

    template<class F> auto optional<T>::map(F f) && - -> ['see below] + -> see below ;

      @@ -1512,7 +1512,7 @@
    • Notes: The return type of this overload - is optional<decltype(f(istd::move(**this))>. + is optional<decltype(f(istd::move(**this)))>.

    diff --git a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/header_optional_optional_refs.html b/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/header_optional_optional_refs.html index 3934957..77906eb 100644 --- a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/header_optional_optional_refs.html +++ b/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/header_optional_optional_refs.html @@ -73,6 +73,8 @@ template<class F> T& value_or_eval( F f ) const ; R + template<class F> auto map( F f ) const -> see below; R + T* get_ptr() const noexcept ; R bool has_value() const noexcept ; R diff --git a/doc/html/index.html b/doc/html/index.html index a37010c..44e9bc0 100644 --- a/doc/html/index.html +++ b/doc/html/index.html @@ -145,7 +145,7 @@

- +

Last revised: June 23, 2018 at 16:25:31 GMT

Last revised: June 23, 2018 at 18:49:36 GMT


diff --git a/test/optional_test_map.cpp b/test/optional_test_map.cpp index 9a9aab2..19348bd 100644 --- a/test/optional_test_map.cpp +++ b/test/optional_test_map.cpp @@ -106,6 +106,34 @@ void test_map() optional oI = oi.map(convert_t()); BOOST_TEST(bool(oI)); BOOST_TEST_EQ(1, oI->i); + + optional o_ = optional().map(convert_t()); + BOOST_TEST(!o_); +} + +optional make_opt_int(int i) +{ + if (i != 0) + return Int(i); + else + return boost::none; +} + +void test_map_optional() +{ + optional o9 (9), o0 (0), o_; + verify_type>>(o9.map(make_opt_int)); + optional> oo9 = o9.map(make_opt_int); + BOOST_TEST(bool(oo9)); + BOOST_TEST(bool(*oo9)); + BOOST_TEST_EQ(9, (**oo9).i); + + optional> oo0 = o0.map(make_opt_int); + BOOST_TEST(bool(oo0)); + BOOST_TEST(!*oo0); + + optional> oo_ = o_.map(make_opt_int); + BOOST_TEST(!oo_); } void test_map_with_lambda() @@ -153,7 +181,9 @@ int main() #endif test_map_with_lambda(); test_map(); + test_map_optional(); test_map_to_ref(); + test_map_optional(); test_map_optional_ref(); return boost::report_errors(); From 250806d029f99f4ce4d4f04de9c7421df4b691f2 Mon Sep 17 00:00:00 2001 From: Andrzej Krzemienski Date: Sun, 24 Jun 2018 15:22:56 +0200 Subject: [PATCH 04/13] fixed >> int C++03 templates --- test/optional_test_map.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/test/optional_test_map.cpp b/test/optional_test_map.cpp index 19348bd..42878da 100644 --- a/test/optional_test_map.cpp +++ b/test/optional_test_map.cpp @@ -62,7 +62,7 @@ int get_val(MoveOnly m) void test_map_move_only() { optional om (makeMoveOnly(7)), om2 (makeMoveOnly(8)); - verify_type>(boost::move(om).map(get_val)); + verify_type >(boost::move(om).map(get_val)); optional oi = boost::move(om2).map(get_val); BOOST_TEST(bool(oi)); BOOST_TEST_EQ(8, *oi); @@ -102,7 +102,7 @@ struct get_ref void test_map() { optional oi (1); - verify_type>(oi.map(convert_t())); + verify_type >(oi.map(convert_t())); optional oI = oi.map(convert_t()); BOOST_TEST(bool(oI)); BOOST_TEST_EQ(1, oI->i); @@ -122,17 +122,17 @@ optional make_opt_int(int i) void test_map_optional() { optional o9 (9), o0 (0), o_; - verify_type>>(o9.map(make_opt_int)); - optional> oo9 = o9.map(make_opt_int); + verify_type > >(o9.map(make_opt_int)); + optional > oo9 = o9.map(make_opt_int); BOOST_TEST(bool(oo9)); BOOST_TEST(bool(*oo9)); BOOST_TEST_EQ(9, (**oo9).i); - optional> oo0 = o0.map(make_opt_int); + optional > oo0 = o0.map(make_opt_int); BOOST_TEST(bool(oo0)); BOOST_TEST(!*oo0); - optional> oo_ = o_.map(make_opt_int); + optional > oo_ = o_.map(make_opt_int); BOOST_TEST(!oo_); } @@ -140,7 +140,7 @@ void test_map_with_lambda() { #ifndef BOOST_NO_CXX11_LAMBDAS optional oi (1), oj(2); - verify_type>(oi.map([](int i){ return i == 1; })); + verify_type >(oi.map([](int i){ return i == 1; })); optional ob = oi.map([](int i){ return i == 1; }); optional oc = oj.map([](int i){ return i == 1; }); BOOST_TEST(bool(ob)); @@ -153,7 +153,7 @@ void test_map_with_lambda() void test_map_to_ref() { optional oi (2); - verify_type>(oi.map(get_ref())); + verify_type >(oi.map(get_ref())); optional ori = oi.map(get_ref()); BOOST_TEST(bool(ori)); *ori = 3; @@ -166,7 +166,7 @@ void test_map_optional_ref() { Int I (5); optional ori (I); - verify_type>(ori.map(get_int_ref)); + verify_type >(ori.map(get_int_ref)); optional orii = ori.map(get_int_ref); BOOST_TEST(bool(orii)); BOOST_TEST_EQ(5, *orii); From 42445e94aa8c9a68fce4af0d4980dc6cf8226e4a Mon Sep 17 00:00:00 2001 From: Andrzej Krzemienski Date: Sun, 24 Jun 2018 17:12:38 +0200 Subject: [PATCH 05/13] Fix for C++03 tests for .map() using result_of --- test/optional_test_map.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/optional_test_map.cpp b/test/optional_test_map.cpp index 42878da..f16c733 100644 --- a/test/optional_test_map.cpp +++ b/test/optional_test_map.cpp @@ -86,6 +86,7 @@ struct Int struct convert_t { + typedef Int result_type; Int operator()(int i) { return Int(i); } }; @@ -96,6 +97,7 @@ int& get_int_ref(Int& i) struct get_ref { + typedef int& result_type; int& operator()(int& i) { return i; } }; From 01694601943ca316bb73f5bcbebfec12e3a1c665 Mon Sep 17 00:00:00 2001 From: Andrzej Krzemienski Date: Mon, 25 Jun 2018 22:50:00 +0200 Subject: [PATCH 06/13] fixed tests and maybe std::is_trivially_default_constructible --- include/boost/optional/detail/experimental_traits.hpp | 4 ++-- test/optional_test_map.cpp | 2 +- test/optional_xconfig_HACK_TO_LIST_PREDEFINED_MACROS.cpp | 9 ++++++++- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/include/boost/optional/detail/experimental_traits.hpp b/include/boost/optional/detail/experimental_traits.hpp index 6eded58..4ac8bc6 100644 --- a/include/boost/optional/detail/experimental_traits.hpp +++ b/include/boost/optional/detail/experimental_traits.hpp @@ -15,8 +15,6 @@ #include #include #include - -namespace boost { namespace optional_detail { // The condition to use POD implementation @@ -52,10 +50,12 @@ namespace boost { namespace optional_detail { #ifndef BOOST_OPTIONAL_DETAIL_USE_STD_TYPE_TRAITS # define BOOST_OPTIONAL_DETAIL_HAS_TRIVIAL_CTOR(T) BOOST_HAS_TRIVIAL_CONSTRUCTOR(T) #else +# include # define BOOST_OPTIONAL_DETAIL_HAS_TRIVIAL_CTOR(T) std::is_trivially_default_constructible::value #endif +namespace boost { namespace optional_detail { #ifndef BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES template diff --git a/test/optional_test_map.cpp b/test/optional_test_map.cpp index f16c733..288249c 100644 --- a/test/optional_test_map.cpp +++ b/test/optional_test_map.cpp @@ -140,7 +140,7 @@ void test_map_optional() void test_map_with_lambda() { -#ifndef BOOST_NO_CXX11_LAMBDAS +#if !defined BOOST_NO_CXX11_LAMBDAS && !defined BOOST_NO_CXX11_DECLTYPE_N3276 optional oi (1), oj(2); verify_type >(oi.map([](int i){ return i == 1; })); optional ob = oi.map([](int i){ return i == 1; }); diff --git a/test/optional_xconfig_HACK_TO_LIST_PREDEFINED_MACROS.cpp b/test/optional_xconfig_HACK_TO_LIST_PREDEFINED_MACROS.cpp index e6b6ba0..aa21cf5 100644 --- a/test/optional_xconfig_HACK_TO_LIST_PREDEFINED_MACROS.cpp +++ b/test/optional_xconfig_HACK_TO_LIST_PREDEFINED_MACROS.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Andrzej Krzemienski. +// Copyright (C) 2015 - 2018 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 @@ -11,6 +11,7 @@ #include "boost/core/lightweight_test.hpp" #include "boost/optional/detail/optional_config.hpp" +#include "boost/predef.h" #include int main() @@ -37,5 +38,11 @@ int main() BOOST_TEST_EQ(empty, __GNUC_PATCHLEVEL__); BOOST_TEST_EQ(empty, __cplusplus); #endif + + BOOST_TEST_EQ(empty, BOOST_COMP_GNUC); + BOOST_TEST_EQ(empty, BOOST_LANG_STDCPP); + BOOST_TEST_EQ(empty, BOOST_LIB_C_GNU); + BOOST_TEST_EQ(empty, BOOST_LIB_STD_CXX); + return boost::report_errors(); } From 35ca7c1ff116af09a3ed34bf3e9e3a46bb80fc1a Mon Sep 17 00:00:00 2001 From: Andrzej Krzemienski Date: Mon, 25 Jun 2018 23:59:19 +0200 Subject: [PATCH 07/13] added a hack test to check compiler setup --- test/Jamfile.v2 | 1 + 1 file changed, 1 insertion(+) diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index f181ec7..bb9acd4 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -72,6 +72,7 @@ import testing ; [ run optional_test_static_properties.cpp ] [ compile optional_test_maybe_uninitialized_warning.cpp ] [ compile optional_test_deleted_default_ctor.cpp ] + [ run optional_xconfig_HACK_TO_LIST_PREDEFINED_MACROS.cpp ] [ run optional_xconfig_NO_PROPER_ASSIGN_FROM_CONST_INT_pass.cpp ] [ run-fail optional_xconfig_NO_PROPER_ASSIGN_FROM_CONST_INT_fail.cpp ] [ run optional_xconfig_NO_PROPER_CONVERT_FROM_CONST_INT_pass.cpp ] From 51a46f95c6789dc6667018155c24764db72d36db Mon Sep 17 00:00:00 2001 From: Andrzej Krzemienski Date: Tue, 26 Jun 2018 00:04:33 +0200 Subject: [PATCH 08/13] testing clang v. --- test/optional_xconfig_HACK_TO_LIST_PREDEFINED_MACROS.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/test/optional_xconfig_HACK_TO_LIST_PREDEFINED_MACROS.cpp b/test/optional_xconfig_HACK_TO_LIST_PREDEFINED_MACROS.cpp index aa21cf5..f8cf269 100644 --- a/test/optional_xconfig_HACK_TO_LIST_PREDEFINED_MACROS.cpp +++ b/test/optional_xconfig_HACK_TO_LIST_PREDEFINED_MACROS.cpp @@ -40,6 +40,7 @@ int main() #endif BOOST_TEST_EQ(empty, BOOST_COMP_GNUC); + BOOST_TEST_EQ(empty, BOOST_COMP_CLANG); BOOST_TEST_EQ(empty, BOOST_LANG_STDCPP); BOOST_TEST_EQ(empty, BOOST_LIB_C_GNU); BOOST_TEST_EQ(empty, BOOST_LIB_STD_CXX); From 7320dd54e89d29f8aec536becb1e501db898551e Mon Sep 17 00:00:00 2001 From: Andrzej Krzemienski Date: Wed, 27 Jun 2018 22:23:57 +0200 Subject: [PATCH 09/13] one more test hack macro to check --- test/optional_xconfig_HACK_TO_LIST_PREDEFINED_MACROS.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/test/optional_xconfig_HACK_TO_LIST_PREDEFINED_MACROS.cpp b/test/optional_xconfig_HACK_TO_LIST_PREDEFINED_MACROS.cpp index f8cf269..202c7ef 100644 --- a/test/optional_xconfig_HACK_TO_LIST_PREDEFINED_MACROS.cpp +++ b/test/optional_xconfig_HACK_TO_LIST_PREDEFINED_MACROS.cpp @@ -43,6 +43,7 @@ int main() BOOST_TEST_EQ(empty, BOOST_COMP_CLANG); BOOST_TEST_EQ(empty, BOOST_LANG_STDCPP); BOOST_TEST_EQ(empty, BOOST_LIB_C_GNU); + BOOST_TEST_EQ(empty, BOOST_LIB_STD_GNU); BOOST_TEST_EQ(empty, BOOST_LIB_STD_CXX); return boost::report_errors(); From d13623884a4dcca5091129f50be4861d6f5f9abb Mon Sep 17 00:00:00 2001 From: Andrzej Krzemienski Date: Thu, 28 Jun 2018 02:10:57 +0200 Subject: [PATCH 10/13] hopefully fixed the libstdc++ 4.9 problem (thanks Jonathan) --- include/boost/optional/detail/experimental_traits.hpp | 8 +++++++- test/Jamfile.v2 | 3 ++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/include/boost/optional/detail/experimental_traits.hpp b/include/boost/optional/detail/experimental_traits.hpp index 4ac8bc6..556aa99 100644 --- a/include/boost/optional/detail/experimental_traits.hpp +++ b/include/boost/optional/detail/experimental_traits.hpp @@ -14,6 +14,7 @@ #include #include +#include #include // The condition to use POD implementation @@ -38,11 +39,16 @@ # define BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES #endif +// GCC 5 or higher, or clang with libc++ or clang with libstdc++ 5 or higher #if __cplusplus >= 201103L # if BOOST_WORKAROUND(BOOST_GCC, >= 50000) # define BOOST_OPTIONAL_DETAIL_USE_STD_TYPE_TRAITS # elif (defined BOOST_CLANG) -# define BOOST_OPTIONAL_DETAIL_USE_STD_TYPE_TRAITS +# if BOOST_LIB_STD_CXX > 0 +# define BOOST_OPTIONAL_DETAIL_USE_STD_TYPE_TRAITS +# elif BOOST_LIB_STD_GNU >= 441200023 && BOOST_LIB_STD_GNU != 450600023 && BOOST_LIB_STD_GNU != 450600026 && BOOST_LIB_STD_GNU != 460800003 +# define BOOST_OPTIONAL_DETAIL_USE_STD_TYPE_TRAITS +# endif # endif #endif diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index bb9acd4..e1690d2 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -23,6 +23,7 @@ import testing ; [ run optional_test_convert_from_T.cpp ] [ run optional_test_empty_braces.cpp ] [ run optional_test_make_optional.cpp ] + #[ run optional_test_flat_map.cpp ] [ run optional_test_map.cpp ] [ run optional_test_tie.cpp ] [ run optional_test_ref_assign_portable_minimum.cpp ] @@ -72,7 +73,7 @@ import testing ; [ run optional_test_static_properties.cpp ] [ compile optional_test_maybe_uninitialized_warning.cpp ] [ compile optional_test_deleted_default_ctor.cpp ] - [ run optional_xconfig_HACK_TO_LIST_PREDEFINED_MACROS.cpp ] + #[ run optional_xconfig_HACK_TO_LIST_PREDEFINED_MACROS.cpp ] [ run optional_xconfig_NO_PROPER_ASSIGN_FROM_CONST_INT_pass.cpp ] [ run-fail optional_xconfig_NO_PROPER_ASSIGN_FROM_CONST_INT_fail.cpp ] [ run optional_xconfig_NO_PROPER_CONVERT_FROM_CONST_INT_pass.cpp ] From 701afd43a4452af5c42ef1d0de3223a36f7fd31b Mon Sep 17 00:00:00 2001 From: Andrzej Krzemienski Date: Thu, 28 Jun 2018 21:17:07 +0200 Subject: [PATCH 11/13] fixed strange verisons of libstdc++ --- include/boost/optional/detail/experimental_traits.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/optional/detail/experimental_traits.hpp b/include/boost/optional/detail/experimental_traits.hpp index 556aa99..b51f5f1 100644 --- a/include/boost/optional/detail/experimental_traits.hpp +++ b/include/boost/optional/detail/experimental_traits.hpp @@ -46,7 +46,7 @@ # elif (defined BOOST_CLANG) # if BOOST_LIB_STD_CXX > 0 # define BOOST_OPTIONAL_DETAIL_USE_STD_TYPE_TRAITS -# elif BOOST_LIB_STD_GNU >= 441200023 && BOOST_LIB_STD_GNU != 450600023 && BOOST_LIB_STD_GNU != 450600026 && BOOST_LIB_STD_GNU != 460800003 +# elif BOOST_LIB_STD_GNU >= 441200023 && BOOST_LIB_STD_GNU != 450600023 && BOOST_LIB_STD_GNU != 450600026 && BOOST_LIB_STD_GNU != 460800003 && BOOST_LIB_STD_GNU != 450400026 && BOOST_LIB_STD_GNU != 460700026 # define BOOST_OPTIONAL_DETAIL_USE_STD_TYPE_TRAITS # endif # endif From 71d797b9ee132b381c2d4f3b5bcca2078b0a5062 Mon Sep 17 00:00:00 2001 From: Andrzej Krzemienski Date: Thu, 28 Jun 2018 23:27:42 +0200 Subject: [PATCH 12/13] added implementation and tests of flat_map() --- .../detail/optional_reference_spec.hpp | 9 + include/boost/optional/optional.hpp | 55 ++++ test/Jamfile.v2 | 2 +- test/optional_test_flat_map.cpp | 275 ++++++++++++++++++ 4 files changed, 340 insertions(+), 1 deletion(-) create mode 100644 test/optional_test_flat_map.cpp diff --git a/include/boost/optional/detail/optional_reference_spec.hpp b/include/boost/optional/detail/optional_reference_spec.hpp index 2e08e30..4be140c 100644 --- a/include/boost/optional/detail/optional_reference_spec.hpp +++ b/include/boost/optional/detail/optional_reference_spec.hpp @@ -170,6 +170,15 @@ public: return none; } + template + optional::type>::type> flat_map(F f) const + { + if (this->has_value()) + return f(get()); + else + return none; + } + #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES optional(T&& /* rhs */) BOOST_NOEXCEPT { detail::prevent_binding_rvalue(); } diff --git a/include/boost/optional/optional.hpp b/include/boost/optional/optional.hpp index 8ee259c..ff39dad 100644 --- a/include/boost/optional/optional.hpp +++ b/include/boost/optional/optional.hpp @@ -758,7 +758,16 @@ class optional_base : public optional_tag storage_type m_storage ; } ; +template +struct optional_value_type +{ +}; +template +struct optional_value_type< ::boost::optional > +{ + typedef T type; +}; #include @@ -1351,6 +1360,33 @@ class optional return none; } + template + optional::type>::type> flat_map(F f) & + { + if (this->has_value()) + return f(get()); + else + return none; + } + + template + optional::type>::type> flat_map(F f) const& + { + if (this->has_value()) + return f(get()); + else + return none; + } + + template + optional::type>::type> flat_map(F f) && + { + if (this->has_value()) + return f(boost::move(get())); + else + return none; + } + #else template value_type value_or_eval ( F f ) const @@ -1378,6 +1414,25 @@ class optional else return none; } + + template + optional::type>::type> flat_map(F f) + { + if (this->has_value()) + return f(get()); + else + return none; + } + + template + optional::type>::type> flat_map(F f) const + { + if (this->has_value()) + return f(get()); + else + return none; + } + #endif bool has_value() const BOOST_NOEXCEPT { return this->is_initialized() ; } diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index e1690d2..4a758da 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -23,7 +23,7 @@ import testing ; [ run optional_test_convert_from_T.cpp ] [ run optional_test_empty_braces.cpp ] [ run optional_test_make_optional.cpp ] - #[ run optional_test_flat_map.cpp ] + [ run optional_test_flat_map.cpp ] [ run optional_test_map.cpp ] [ run optional_test_tie.cpp ] [ run optional_test_ref_assign_portable_minimum.cpp ] diff --git a/test/optional_test_flat_map.cpp b/test/optional_test_flat_map.cpp new file mode 100644 index 0000000..409e111 --- /dev/null +++ b/test/optional_test_flat_map.cpp @@ -0,0 +1,275 @@ +// Copyright (C) 2018 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/optional.hpp" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#include "boost/core/ignore_unused.hpp" +#include "boost/core/is_same.hpp" +#include "boost/core/lightweight_test.hpp" +#include "boost/core/lightweight_test_trait.hpp" + + +using boost::optional; +using boost::make_optional; +using boost::core::is_same; + +template +void verify_type(Deduced) +{ + BOOST_TEST_TRAIT_TRUE(( is_same )); +} + +struct Int +{ + int i; + explicit Int(int i_) : i(i_) {} +}; + +struct convert_t +{ + typedef optional result_type; + optional operator()(int i) { if (i != 0) return Int(i); else return boost::none; } +}; + +void test_flat_map_on_mutable_optional_with_function_object() +{ + { + optional oi (1); + verify_type< optional >(oi.flat_map(convert_t())); + optional oI = oi.flat_map(convert_t()); + BOOST_TEST(bool(oI)); + BOOST_TEST_EQ(1, oI->i); + } + { + optional oi (0); + optional oI = oi.flat_map(convert_t()); + BOOST_TEST(!oI); + } + { + optional oi; + optional oI = oi.flat_map(convert_t()); + BOOST_TEST(!oI); + } +} + +void test_flat_map_on_const_optional_with_function_object() +{ + { + const optional oi (1); + verify_type< optional >(oi.flat_map(convert_t())); + optional oI = oi.flat_map(convert_t()); + BOOST_TEST(bool(oI)); + BOOST_TEST_EQ(1, oI->i); + } + { + const optional oi (0); + optional oI = oi.flat_map(convert_t()); + BOOST_TEST(!oI); + } + { + const optional oi; + optional oI = oi.flat_map(convert_t()); + BOOST_TEST(!oI); + } +} + +void test_flat_map_with_lambda() +{ +#if !defined BOOST_NO_CXX11_LAMBDAS && !defined BOOST_NO_CXX11_DECLTYPE_N3276 + { + optional oi (1); + verify_type< optional >(oi.flat_map([](int i){ return optional(i == 0, Int(i)); })); + optional oI = oi.flat_map([](int i){ return optional(i != 0, Int(i)); }); + BOOST_TEST(bool(oI)); + BOOST_TEST_EQ(1, oI->i); + } + { + optional oi (0); + optional oI = oi.flat_map([](int i){ return optional(i != 0, Int(i)); }); + BOOST_TEST(!oI); + } + { + optional oi; + optional oI = oi.flat_map([](int i){ return optional(i != 0, Int(i)); }); + BOOST_TEST(!oI); + } +#endif // lambdas +} + +struct get_opt_ref +{ + typedef optional result_type; + optional operator()(int& i) { return i != 0 ? optional(i) : optional(); } +}; + +void test_flat_map_obj_to_ref() +{ + { + optional oi (2); + verify_type< optional >(oi.flat_map(get_opt_ref())); + optional ori = oi.flat_map(get_opt_ref()); + BOOST_TEST(bool(ori)); + BOOST_TEST_EQ(2, *ori); + *ori = 3; + BOOST_TEST(bool(oi)); + BOOST_TEST_EQ(3, *oi); + BOOST_TEST_EQ(3, *ori); + } + { + optional oi (0); + optional ori = oi.flat_map(get_opt_ref()); + BOOST_TEST(!ori); + } + { + optional oi; + optional ori = oi.flat_map(get_opt_ref()); + BOOST_TEST(!ori); + } +} + +optional get_opt_int_ref(Int& i) +{ + return i.i ? optional(i.i) : optional(); +} + +void test_flat_map_ref_to_ref() +{ + { + Int I (5); + optional orI (I); + verify_type< optional >(orI.flat_map(get_opt_int_ref)); + optional ori = orI.flat_map(get_opt_int_ref); + BOOST_TEST(bool(ori)); + BOOST_TEST_EQ(5, *ori); + *ori = 6; + BOOST_TEST_EQ(6, *ori); + BOOST_TEST_EQ(6, I.i); + } + { + Int I (0); + optional orI (I); + optional ori = orI.flat_map(get_opt_int_ref); + BOOST_TEST(!ori); + } + { + optional orI; + optional ori = orI.flat_map(get_opt_int_ref); + BOOST_TEST(!ori); + } +} + +optional< optional > make_opt_int(int i) +{ + if (i == 0) + return boost::none; + else if (i == 1) + return boost::make_optional(optional()); + else + return boost::make_optional(boost::make_optional(Int(i))); +} + +void test_flat_map_opt_opt() +{ + { + optional oi (9); + verify_type > >(oi.flat_map(make_opt_int)); + optional > ooI = oi.flat_map(make_opt_int); + BOOST_TEST(bool(ooI)); + BOOST_TEST(bool(*ooI)); + BOOST_TEST_EQ(9, (**ooI).i); + } + { + optional oi (1); + optional > ooI = oi.flat_map(make_opt_int); + BOOST_TEST(bool(ooI)); + BOOST_TEST(!*ooI); + } + { + optional oi (0); + optional > ooI = oi.flat_map(make_opt_int); + BOOST_TEST(!ooI); + } + { + optional oi; + optional > ooI = oi.flat_map(make_opt_int); + BOOST_TEST(!ooI); + } +} + +#if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) +struct MoveOnly +{ + int value; + explicit MoveOnly(int i) : value(i) {} + MoveOnly(MoveOnly && r) : value(r.value) { r.value = 0; } + MoveOnly& operator=(MoveOnly && r) { value = r.value; r.value = 0; return *this; } + +private: + MoveOnly(MoveOnly const&); + void operator=(MoveOnly const&); +}; + +MoveOnly makeMoveOnly(int i) +{ + return MoveOnly(i); +} + +optional makeOptMoveOnly(int i) +{ + return optional(MoveOnly(i)); +} + +optional get_val(MoveOnly m) +{ + return optional(m.value != 0, m.value); +} + +void test_flat_map_move_only() +{ + { + optional om (makeMoveOnly(1)), om2 (makeMoveOnly(2)); + verify_type >(boost::move(om).flat_map(get_val)); + optional oi = boost::move(om2).flat_map(get_val); + BOOST_TEST(bool(oi)); + BOOST_TEST_EQ(2, *oi); + } + { + optional oj = makeOptMoveOnly(4).flat_map(get_val); + BOOST_TEST(bool(oj)); + BOOST_TEST_EQ(4, *oj); + } + { + optional oj = optional().flat_map(get_val); + BOOST_TEST(!oj); + } +} + +#endif // no rvalue refs + +int main() +{ + test_flat_map_on_mutable_optional_with_function_object(); + test_flat_map_on_const_optional_with_function_object(); + test_flat_map_with_lambda(); + test_flat_map_obj_to_ref(); + test_flat_map_ref_to_ref(); + test_flat_map_opt_opt(); + +#if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) + test_flat_map_move_only(); +#endif + + return boost::report_errors(); +} From d0b87d2f359f8fa4fa31c84ca03e0e18576a7c11 Mon Sep 17 00:00:00 2001 From: Andrzej Krzemienski Date: Mon, 2 Jul 2018 23:07:47 +0200 Subject: [PATCH 13/13] documented flat_map --- doc/27_ref_optional_synopsis.qbk | 89 ++++++++-------- doc/28_ref_optional_semantics.qbk | 100 +++++++++++++----- doc/91_relnotes.qbk | 7 +- ...ailed_semantics___optional_references.html | 24 +++++ .../detailed_semantics___optional_values.html | 76 +++++++++++++ .../header_optional_optional_refs.html | 3 +- .../header_optional_optional_values.html | 4 + doc/html/boost_optional/relnotes.html | 5 +- doc/html/index.html | 2 +- 9 files changed, 236 insertions(+), 74 deletions(-) diff --git a/doc/27_ref_optional_synopsis.qbk b/doc/27_ref_optional_synopsis.qbk index 5d4c2e4..7114b43 100644 --- a/doc/27_ref_optional_synopsis.qbk +++ b/doc/27_ref_optional_synopsis.qbk @@ -17,16 +17,16 @@ class in_place_init_t { /* see below */ } ; ``[link reference_in_place_init __GO_TO__]`` const in_place_init_t in_place_init ( /* see below */ ) ; - + class in_place_init_if_t { /*see below*/ } ; ``[link reference_in_place_init_if __GO_TO__]`` const in_place_init_if_t in_place_init_if ( /*see below*/ ) ; - + template class optional ; ``[link reference_operator_template __GO_TO__]`` - + template class optional ; ``[link reference_operator_template_spec __GO_TO__]`` - + template inline bool operator == ( optional const& x, optional const& y ) ; ``[link reference_operator_compare_equal_optional_optional __GO_TO__]`` template inline bool operator != ( optional const& x, optional const& y ) ; ``[link reference_operator_compare_not_equal_optional_optional __GO_TO__]`` @@ -38,21 +38,21 @@ template inline bool operator <= ( optional const& x, optional const& y ) ; ``[link reference_operator_compare_less_or_equal_optional_optional __GO_TO__]`` template inline bool operator >= ( optional const& x, optional const& y ) ; ``[link reference_operator_compare_greater_or_equal_optional_optional __GO_TO__]`` - + template inline bool operator == ( optional const& x, none_t ) noexcept ; ``[link reference_operator_compare_equal_optional_none __GO_TO__]`` template inline bool operator != ( optional const& x, none_t ) noexcept ; ``[link reference_operator_compare_not_equal_optional_none __GO_TO__]`` template inline optional make_optional ( T const& v ) ; ``[link reference_make_optional_value __GO_TO__]`` - + template inline optional> make_optional ( T && v ) ; ``[link reference_make_optional_rvalue __GO_TO__]`` template inline optional make_optional ( bool condition, T const& v ) ; ``[link reference_make_optional_bool_value __GO_TO__]`` - + template inline optional> make_optional ( bool condition, T && v ) ; ``[link reference_make_optional_bool_rvalue __GO_TO__]`` - template inline auto get_optional_value_or ( optional const& opt, typename optional::reference_const_type def ) -> typename optional::reference_const_type; ``[link reference_free_get_value_or __GO_TO__]`` - + template inline auto get_optional_value_or ( optional const& opt, typename optional::reference_const_type def ) -> typename optional::reference_const_type; ``[link reference_free_get_value_or __GO_TO__]`` + template inline auto get_optional_value_or ( optional const& opt, typename optional::reference_type def ) -> typename optional::reference_type ; ``[link reference_free_get_value_or __GO_TO__]`` template inline T const& get ( optional const& opt ) ; ``[link reference_optional_get __GO_TO__]`` @@ -68,7 +68,7 @@ template inline auto get_pointer ( optional & opt ) -> ``['see below]``; ``[link reference_free_get_pointer __GO_TO__]`` template inline void swap( optional& x, optional& y ) ; ``[link reference_swap_optional_optional __GO_TO__]`` - + template inline void swap( optional& x, optional& y ) ; ``[link reference_swap_optional_reference __GO_TO__]`` } // namespace boost @@ -86,21 +86,21 @@ class in_place_init_t { /* see below */ } ; const in_place_init_t in_place_init ( /* see below */ ) ; - + class in_place_init_if_t { /*see below*/ } ; const in_place_init_if_t in_place_init_if ( /*see below*/ ) ; - + } -Classes `in_place_init_t` and `in_place_init_if_t` are empty clsses. Their purpose is to control overload resolution in the initialization of optional objects. -They are empty, trivially copyable classes with disabled default constructor. +Classes `in_place_init_t` and `in_place_init_if_t` are empty clsses. Their purpose is to control overload resolution in the initialization of optional objects. +They are empty, trivially copyable classes with disabled default constructor. [endsect] [section:header_optional_optional_values Optional Values] [#reference_operator_template] - + template class optional { @@ -112,27 +112,27 @@ They are empty, trivially copyable classes with disabled default constructor. typedef T && rval_reference_type ; typedef T * pointer_type ; typedef T const* pointer_const_type ; - + optional () noexcept ; ``[link reference_optional_constructor __GO_TO__]`` optional ( none_t ) noexcept ; ``[link reference_optional_constructor_none_t __GO_TO__]`` optional ( T const& v ) ; ``[link reference_optional_constructor_value __GO_TO__]`` - + optional ( T&& v ) ; ``[link reference_optional_constructor_move_value __GO_TO__]`` - optional ( bool condition, T const& v ) ; ``[link reference_optional_constructor_bool_value __GO_TO__]`` + optional ( bool condition, T const& v ) ; ``[link reference_optional_constructor_bool_value __GO_TO__]`` optional ( optional const& rhs ) ; ``[link reference_optional_constructor_optional __GO_TO__]`` - + optional ( optional&& rhs ) noexcept(``['see below]``) ; ``[link reference_optional_move_constructor_optional __GO_TO__]`` template explicit optional ( optional const& rhs ) ; ``[link reference_optional_constructor_other_optional __GO_TO__]`` - + template explicit optional ( optional&& rhs ) ; ``[link reference_optional_move_constructor_other_optional __GO_TO__]`` - + template explicit optional ( in_place_init_t, Args&&... args ) ; ``[link reference_optional_in_place_init __GO_TO__]`` - + template explicit optional ( in_place_init_if_t, bool condition, Args&&... args ) ; ``[link reference_optional_in_place_init_if __GO_TO__]`` template explicit optional ( InPlaceFactory const& f ) ; ``[link reference_optional_constructor_factory __GO_TO__]`` @@ -142,17 +142,17 @@ They are empty, trivially copyable classes with disabled default constructor. optional& operator = ( none_t ) noexcept ; ``[link reference_optional_operator_equal_none_t __GO_TO__]`` optional& operator = ( T const& v ) ; ``[link reference_optional_operator_equal_value __GO_TO__]`` - + optional& operator = ( T&& v ) ; ``[link reference_optional_operator_move_equal_value __GO_TO__]`` optional& operator = ( optional const& rhs ) ; ``[link reference_optional_operator_equal_optional __GO_TO__]`` - + optional& operator = ( optional&& rhs ) noexcept(``['see below]``) ; ``[link reference_optional_operator_move_equal_optional __GO_TO__]`` template optional& operator = ( optional const& rhs ) ; ``[link reference_optional_operator_equal_other_optional __GO_TO__]`` - + template optional& operator = ( optional&& rhs ) ; ``[link reference_optional_operator_move_equal_other_optional __GO_TO__]`` - + template void emplace ( Args&&... args ) ; ``[link reference_optional_emplace __GO_TO__]`` template optional& operator = ( InPlaceFactory const& f ) ; ``[link reference_optional_operator_equal_factory __GO_TO__]`` @@ -168,14 +168,14 @@ They are empty, trivially copyable classes with disabled default constructor. T const& operator *() const& ; ``[link reference_optional_operator_asterisk __GO_TO__]`` T& operator *() & ; ``[link reference_optional_operator_asterisk __GO_TO__]`` T&& operator *() && ; ``[link reference_optional_operator_asterisk_move __GO_TO__]`` - + T const& value() const& ; ``[link reference_optional_value __GO_TO__]`` T& value() & ; ``[link reference_optional_value __GO_TO__]`` T&& value() && ; ``[link reference_optional_value_move __GO_TO__]`` - + template T value_or( U && v ) const& ; ``[link reference_optional_value_or __GO_TO__]`` template T value_or( U && v ) && ; ``[link reference_optional_value_or_move __GO_TO__]`` - + template T value_or_eval( F f ) const& ; ``[link reference_optional_value_or_call __GO_TO__]`` template T value_or_eval( F f ) && ; ``[link reference_optional_value_or_call_move __GO_TO__]`` @@ -183,11 +183,15 @@ They are empty, trivially copyable classes with disabled default constructor. template auto map( F f ) & -> ``['see below]``; ``[link reference_optional_map __GO_TO__]`` template auto map( F f ) && -> ``['see below]``; ``[link reference_optional_map_move __GO_TO__]`` + template auto flat_map( F f ) const& -> ``['see below]``; ``[link reference_optional_flat_map __GO_TO__]`` + template auto flat_map( F f ) & -> ``['see below]``; ``[link reference_optional_flat_map __GO_TO__]`` + template auto flat_map( F f ) && -> ``['see below]``; ``[link reference_optional_flat_map_move __GO_TO__]`` + T const* get_ptr() const ; ``[link reference_optional_get_ptr __GO_TO__]`` T* get_ptr() ; ``[link reference_optional_get_ptr __GO_TO__]`` bool has_value() const noexcept ; ``[link reference_optional_operator_bool __GO_TO__]`` - + explicit operator bool() const noexcept ; ``[link reference_optional_operator_bool __GO_TO__]`` bool operator!() const noexcept ; ``[link reference_optional_operator_not __GO_TO__]`` @@ -204,7 +208,7 @@ They are empty, trivially copyable classes with disabled default constructor. bool is_initialized() const ; ``[link reference_optional_is_initialized __GO_TO__]`` // (deprecated) - T const& get_value_or( T const& default ) const ; ``[link reference_optional_get_value_or_value __GO_TO__]`` + T const& get_value_or( T const& default ) const ; ``[link reference_optional_get_value_or_value __GO_TO__]`` }; @@ -231,22 +235,21 @@ They are empty, trivially copyable classes with disabled default constructor. optional ( none_t ) noexcept ; ``[link reference_optional_ref_default_ctor __GO_TO__]`` template optional(R&& r) noexcept ; ``[link reference_optional_ref_value_ctor __GO_TO__]`` - + template optional(bool cond, R&& r) noexcept ; ``[link reference_optional_ref_cond_value_ctor __GO_TO__]`` - + optional ( optional const& rhs ) noexcept ; ``[link reference_optional_ref_copy_ctor __GO_TO__]`` template explicit optional ( optional const& rhs ) noexcept ; ``[link reference_optional_ref_ctor_from_opt_U __GO_TO__]`` optional& operator = ( none_t ) noexcept ; ``[link reference_optional_ref_assign_none_t __GO_TO__]`` - optional& operator = ( optional const& rhs ) noexcept; ``[link reference_optional_ref_copy_assign __GO_TO__]`` template optional& operator = ( optional const& rhs ) noexcept ; ``[link reference_optional_ref_assign_optional_U __GO_TO__]`` - - template optional& operator = (R&& r) noexcept ; ``[link reference_optional_ref_assign_R __GO_TO__]`` - + + template optional& operator = (R&& r) noexcept ; ``[link reference_optional_ref_assign_R __GO_TO__]`` + template void emplace ( R&& r ) noexcept ; ``[link reference_optional_ref_emplace_R __GO_TO__]`` T& get() const ; ``[link reference_optional_ref_get __GO_TO__]`` @@ -255,17 +258,19 @@ They are empty, trivially copyable classes with disabled default constructor. T* operator ->() const ; ``[link reference_optional_ref_arrow __GO_TO__]`` T& value() const& ; ``[link reference_optional_ref_value __GO_TO__]`` - + template T& value_or( R && r ) const noexcept ; ``[link reference_optional_ref_value_or __GO_TO__]`` - + template T& value_or_eval( F f ) const ; ``[link reference_optional_ref_value_or_eval __GO_TO__]`` template auto map( F f ) const -> ``['see below]``; ``[link reference_optional_ref_map __GO_TO__]`` + template auto flat_map( F f ) const -> ``['see below]``; ``[link reference_optional_ref_flat_map __GO_TO__]`` + T* get_ptr() const noexcept ; ``[link reference_optional_ref_get_ptr __GO_TO__]`` bool has_value() const noexcept ; ``[link reference_optional_ref_operator_bool __GO_TO__]`` - + explicit operator bool() const noexcept ; ``[link reference_optional_ref_operator_bool __GO_TO__]`` bool operator!() const noexcept ; ``[link reference_optional_ref_operator_not __GO_TO__]`` @@ -282,8 +287,8 @@ They are empty, trivially copyable classes with disabled default constructor. bool is_initialized() const noexcept ; ``[link reference_optional_ref_is_initialized __GO_TO__]`` // (deprecated) - template T& get_value_or( R && r ) constnoexcept; ``[link reference_optional_ref_get_value_or_value __GO_TO__]`` - + template T& get_value_or( R && r ) constnoexcept; ``[link reference_optional_ref_get_value_or_value __GO_TO__]`` + private: T* ref; // exposition only }; diff --git a/doc/28_ref_optional_semantics.qbk b/doc/28_ref_optional_semantics.qbk index b615e35..6ce0d2e 100644 --- a/doc/28_ref_optional_semantics.qbk +++ b/doc/28_ref_optional_semantics.qbk @@ -233,7 +233,7 @@ __SPACE__ arguments `std::forward(args)...`. * [*Postconditions:] `*this` is initialized. * [*Throws:] Any exception thrown by the selected constructor of `T`. -* [*Notes: ] `T` need not be __MOVE_CONSTRUCTIBLE__. On compilers that do not suppor variadic templates or rvalue references, this constuctor is available in limited functionality. For details [link optional_emplace_workaround see here]. +* [*Notes: ] `T` need not be __MOVE_CONSTRUCTIBLE__. On compilers that do not suppor variadic templates or rvalue references, this constuctor is available in limited functionality. For details [link optional_emplace_workaround see here]. * [*Example:] `` @@ -257,7 +257,7 @@ __SPACE__ * [*Effect:] If `condition` is `true`, initializes the contained value as if direct-non-list-initializing an object of type `T` with the arguments `std::forward(args)...`. * [*Postconditions:] `bool(*this) == condition`. * [*Throws:] Any exception thrown by the selected constructor of `T`. -* [*Notes: ] `T` need not be __MOVE_CONSTRUCTIBLE__. On compilers that do not suppor variadic templates or rvalue references, this constuctor is available in limited functionality. For details [link optional_emplace_workaround see here]. +* [*Notes: ] `T` need not be __MOVE_CONSTRUCTIBLE__. On compilers that do not suppor variadic templates or rvalue references, this constuctor is available in limited functionality. For details [link optional_emplace_workaround see here]. * [*Example:] `` @@ -376,13 +376,13 @@ __SPACE__ * [*Requires:] `T` is __COPY_CONSTRUCTIBLE__ and `CopyAssignable`. * [*Effects:] [table - [] + [] [[][[*`*this` contains a value]][[*`*this` does not contain a value]]] [[[*`rhs` contains a value]][assigns `*rhs` to the contained value][initializes the contained value as if direct-initializing an object of type `T` with `*rhs`]] [[[*`rhs` does not contain a value]][destroys the contained value by calling `val->T::~T()`][no effect]] ] * [*Returns:] `*this`; -* [*Postconditions:] `bool(rhs) == bool(*this)`. +* [*Postconditions:] `bool(rhs) == bool(*this)`. * [*Exception Safety:] If any exception is thrown, the initialization state of `*this` and `rhs` remains unchanged. If an exception is thrown during the call to `T`'s copy constructor, no effect. If an exception is thrown during the call to `T`'s copy assignment, the state of its contained value is as defined by the exception safety guarantee of `T`'s copy assignment. @@ -406,14 +406,14 @@ __SPACE__ * [*Requires:] `T` is __MOVE_CONSTRUCTIBLE__ and `MoveAssignable`. * [*Effects:] -[table +[table [] [[][[*`*this` contains a value]][[*`*this` does not contain a value]]] [[[*`rhs` contains a value]][assigns `std::move(*rhs)` to the contained value][initializes the contained value as if direct-initializing an object of type `T` with `std::move(*rhs)`]] [[[*`rhs` does not contain a value]][destroys the contained value by calling `val->T::~T()`][no effect]] ] * [*Returns:] `*this`; -* [*Postconditions:] `bool(rhs) == bool(*this)`. +* [*Postconditions:] `bool(rhs) == bool(*this)`. * [*Remarks:] The expression inside `noexcept` is equivalent to `is_nothrow_move_constructible::value && is_nothrow_move_assignable::value`. * [*Exception Safety:] If any exception is thrown, the initialization state of `*this` and `rhs` remains unchanged. If an exception is thrown during the call to `T`'s move constructor, the state of `*rhs` is determined by the exception safety guarantee @@ -437,15 +437,15 @@ __SPACE__ [: `template optional& optional::operator= ( optional const& rhs ) ;`] -* [*Effect:] -[table +* [*Effect:] +[table [] [[][[*`*this` contains a value]][[*`*this` does not contain a value]]] [[[*`rhs` contains a value]][assigns `*rhs` to the contained value][initializes the contained value as if direct-initializing an object of type `T` with `*rhs`]] [[[*`rhs` does not contain a value]][destroys the contained value by calling `val->T::~T()`][no effect]] ] * [*Returns:] `*this`. -* [*Postconditions:] `bool(rhs) == bool(*this)`. +* [*Postconditions:] `bool(rhs) == bool(*this)`. * [*Exception Safety:] If any exception is thrown, the result of the expression `bool(*this)` remains unchanged. If an exception is thrown during the call to `T`'s constructor, no effect. If an exception is thrown during the call to `T`'s assignment, the state of its contained value is as defined by the exception safety guarantee of `T`'s copy assignment. @@ -467,13 +467,13 @@ __SPACE__ * [*Effect:] [table - [] + [] [[][[*`*this` contains a value]][[*`*this` does not contain a value]]] [[[*`rhs` contains a value]][assigns `std::move(*rhs)` to the contained value][initializes the contained value as if direct-initializing an object of type `T` with `std::move(*rhs)`]] [[[*`rhs` does not contain a value]][destroys the contained value by calling `val->T::~T()`][no effect]] ] * [*Returns:] `*this`. -* [*Postconditions:] `bool(rhs) == bool(*this)`. +* [*Postconditions:] `bool(rhs) == bool(*this)`. * [*Exception Safety:] If any exception is thrown, the result of the expression `bool(*this)` remains unchanged. If an exception is thrown during the call to `T`'s constructor, no effect. If an exception is thrown during the call to `T`'s assignment, the state of its contained value is as defined by the exception safety guarantee of `T`'s copy assignment. @@ -485,7 +485,7 @@ optional opt1; opt1 = std::move(opt0) ; assert ( opt0 ); -assert ( opt1 ) +assert ( opt1 ) assert ( *opt1 == static_cast(v) ) ; `` @@ -498,11 +498,11 @@ __SPACE__ * [*Requires:] The compiler supports rvalue references and variadic templates. * [*Effect:] If `*this` is initialized calls `*this = none`. Then initializes in-place the contained value as if direct-initializing an object - of type `T` with `std::forward(args)...`. + of type `T` with `std::forward(args)...`. * [*Postconditions: ] `*this` is [_initialized]. * [*Throws:] Whatever the selected `T`'s constructor throws. * [*Exception Safety:] If an exception is thrown during the initialization of `T`, `*this` is ['uninitialized]. -* [*Notes:] `T` need not be __MOVE_CONSTRUCTIBLE__ or `MoveAssignable`. On compilers that do not suppor variadic templates or rvalue references, this function is available in limited functionality. For details [link optional_emplace_workaround see here]. +* [*Notes:] `T` need not be __MOVE_CONSTRUCTIBLE__ or `MoveAssignable`. On compilers that do not suppor variadic templates or rvalue references, this function is available in limited functionality. For details [link optional_emplace_workaround see here]. * [*Example:] `` T v; @@ -691,7 +691,16 @@ __SPACE__ [: `template auto optional::map(F f) & -> `['see below]` ;`] * [*Effects:] `if (*this) return f(**this); else return none;` -* [*Notes:] The return type of these overloads is `optional`. On compilers that do not support ref-qualifiers on member functions, these two (as well as the next one) overloads are replaced with good old const and non-const overloads. +* [*Notes:] The return type of these overloads is `optional`. On compilers that do not support ref-qualifiers on member functions, these two (as well as the next one) overloads are replaced with good old const and non-const overloads. +* [*Example:] +`` +auto length = [](const string& s){ return s.size(); }; +optional o1 {}, o2 {"cat"}; +optional os1 = o1.map(length), os2 = o2.map(length); +assert ( !os1 ) ; +assert ( os2 ) ; +assert ( *os2 == 3 ) ; +`` __SPACE__ @@ -704,6 +713,37 @@ __SPACE__ __SPACE__ +[#reference_optional_flat_map] + +[: `template auto optional::flat_map(F f) const& -> `['see below]` ;`] +[: `template auto optional::flat_map(F f) & -> `['see below]` ;`] + +* [*Requires:] The return type of expression `f(**this)` is `optional` for some object or reference type `U`. +* [*Effects:] `if (*this) return f(**this); else return none;` +* [*Notes:] The return type of these overloads is `optional`. On compilers that do not support ref-qualifiers on member functions, these two (as well as the next one) overloads are replaced with good old const and non-const overloads. +* [*Example:] +`` +optional first_char(const string& s) { + return s.empty() ? none : optional(s[0]); +}; +optional o1 {}, o2 {"cat"}; +optional os1 = o1.flat_map(first_char), os2 = o2.flat_map(first_char); +assert ( !os1 ) ; +assert ( os2 ) ; +assert ( *os2 == 'c' ) ; +`` +__SPACE__ + +[#reference_optional_flat_map_move] + +[: `template auto optional::flat_map(F f) && -> `['see below]` ;`] + +* [*Requires:] The return type of expression `f(std::move(**this))` is `optional` for some object or reference type `U`. +* [*Effects:] `if (*this) return f(std::move(**this)); else return none;` +* [*Notes:] The return type of this overload is `optional`. + +__SPACE__ + [#reference_optional_get_value_or_value] [: `T const& optional::get_value_or( T const& default) const ;`] @@ -835,7 +875,7 @@ __SPACE__ [: `template optional::optional(R&& r) noexcept;`] * [*Postconditions:] `bool(*this) == true`; `addressof(**this) == addressof(r)`. * [*Remarks:] Unless `R` is an lvalue reference, the program is ill-formed. This constructor does not participate in overload resolution if `decay` is an instance of `boost::optional`. -* [*Notes:] This constructor is declared `explicit` on compilers that do not correctly suport binding to const lvalues of integral types. For more details [link optional_reference_binding see here]. +* [*Notes:] This constructor is declared `explicit` on compilers that do not correctly suport binding to const lvalues of integral types. For more details [link optional_reference_binding see here]. * [*Example:] `` T v; @@ -862,7 +902,7 @@ __SPACE__ [: `optional::optional ( optional const& rhs ) noexcept ;`] * [*Effects: ] Initializes `ref` with expression `rhs.ref`. - + * [*Postconditions:] `bool(*this) == bool(rhs)`. * [*Example:] @@ -895,7 +935,7 @@ __SPACE__ * [*Requires:] `is_convertible::value` is `true`. * [*Effects: ] Initializes `ref` with expression `rhs.ref`. - + * [*Postconditions:] `bool(*this) == bool(rhs)`. @@ -911,7 +951,7 @@ __SPACE__ * [*Postconditions:] `bool(*this) == false`. - + [#reference_optional_ref_copy_assign] @@ -959,7 +999,7 @@ assert ( *ora == 4 ) ; * [*returns:] `*this`. * [*Postconditions:] `bool(*this) == bool(rhs)`. - + __SPACE__ @@ -970,7 +1010,7 @@ __SPACE__ * [*Effects: ] Assigns `ref` with expression `r`. * [*returns:] `*this`. - + * [*Postconditions:] `bool(*this) == true`. * [*Remarks:] Unless `R` is an lvalue reference, the program is ill-formed. This function does not participate in overload resolution if `decay` is an instance of `boost::optional`. @@ -1035,13 +1075,13 @@ __SPACE__ [#reference_optional_ref_value] [: `T& optional::value() const ;`] -* [*Effects:] Equivalent to `return bool(*this) ? *val : throw bad_optional_access();`. +* [*Effects:] Equivalent to `return bool(*this) ? *val : throw bad_optional_access();`. __SPACE__ [#reference_optional_ref_value_or] [: `template T& optional::value_or( R&& r ) const noexcept;`] -* [*Effects:] Equivalent to `if (*this) return **this; else return r;`. +* [*Effects:] Equivalent to `if (*this) return **this; else return r;`. * [*Remarks:] Unless `R` is an lvalue reference, the program is ill-formed. __SPACE__ @@ -1060,6 +1100,14 @@ __SPACE__ __SPACE__ +[#reference_optional_ref_flat_map] +[: `template auto optional::flat_map( F f ) const -> `['see below]`;`] +* [*Requires:] The return type of expression `f(**this)` is `optional` for some object or reference type `U`. +* [*Effects:] Equivalent to `if (*this) return f(**this); else return none;`. +* [*Remarks:] The return type of this function is `optional`. + +__SPACE__ + [#reference_optional_ref_get_ptr] [: `T* optional::get_ptr () const noexcept;`] * [*Returns:] `ref`. @@ -1102,9 +1150,9 @@ __SPACE__ [#reference_optional_ref_get_value_or_value] [: `template T& optional::get_value_or( R&& r ) const noexcept;`] -* [*Effects:] Equivalent to `return value_or(std::forward(r);`. +* [*Effects:] Equivalent to `return value_or(std::forward(r);`. * [*Remarks:] This function is depprecated. - + [endsect] @@ -1303,7 +1351,7 @@ __SPACE__ * [*Requires:] Lvalues of type `T` shall be swappable and `T` shall be __MOVE_CONSTRUCTIBLE__. * [*Effects:] -[table +[table [] [[][[*`*this` contains a value]][[*`*this` does not contain a value]]] [[[*`rhs` contains a value]][calls `swap(*(*this), *rhs)`][initializes the contained value of `*this` as if direct-initializing an object of type `T` with the expression `std::move(*rhs)`, followed by `rhs.val->T::~T()`, `*this` contains a value and `rhs` does not contain a value]] diff --git a/doc/91_relnotes.qbk b/doc/91_relnotes.qbk index 79bb200..b7d410f 100644 --- a/doc/91_relnotes.qbk +++ b/doc/91_relnotes.qbk @@ -14,7 +14,8 @@ [heading Boost Release 1.68] * Added member function `has_value()` for compatibility with `std::optional` ([@https://github.com/boostorg/optional/issues/52 issue #52]). -* Added member function `map()` for transforming `optional` into `optional` using a function of type `U(T)`. +* Added member function `map()` for transforming `optional` into `optional` using a function of type `T -> U`. +* Added member function `flat_map()` for transforming `optional` into `optional` using a function of type `T -> optonal`. [heading Boost Release 1.67] @@ -26,7 +27,7 @@ [heading Boost Release 1.66] * On newer compilers `optional` is now trivially-copyable for scalar `T`s. This uses a different storage (just `T` rather than `aligned_storage`). We require the compiler to support defaulted functions. -* Changed the implementation of `operator==` to get rid of the `-Wmaybe-uninitialized` false-positive warning from GCC. +* Changed the implementation of `operator==` to get rid of the `-Wmaybe-uninitialized` false-positive warning from GCC. [heading Boost Release 1.63] * Added two new in-place constructors. They work similarly to `emplace()` functions: they initialize the contained value by perfect-forwarding the obtained arguments. One constructor always initializes the contained value, the other based on a boolean condition. @@ -70,7 +71,7 @@ * IOStream operators are now mentioned in documentation. * Added a way to manually disable move semantics: just define macro `BOOST_OPTIONAL_CONFIG_NO_RVALUE_REFERENCES`. This can be used to work around [@https://svn.boost.org/trac/boost/ticket/10399 Trac #10399]. * It is no longer possible to assign `optional` to `optional` when `U` is not assignable or convertible to `T` ([@https://svn.boost.org/trac/boost/ticket/11087 Trac #11087]). -* Value accessors now work correctly on rvalues of `optional` ([@https://svn.boost.org/trac/boost/ticket/10839 Trac #10839]). +* Value accessors now work correctly on rvalues of `optional` ([@https://svn.boost.org/trac/boost/ticket/10839 Trac #10839]). [heading Boost Release 1.57] diff --git a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics___optional_references.html b/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics___optional_references.html index acb6775..99b8cb8 100644 --- a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics___optional_references.html +++ b/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics___optional_references.html @@ -422,6 +422,30 @@ is optional<decltype(f(**this))>. +

+ space +

+

+ template<class F> auto optional<T&>::flat_map( + F f + ) const + -> see below; +

+
    +
  • + Requires: The return type of expression + f(**this) + is optional<U> + for some object or reference type U. +
  • +
  • + Effects: Equivalent to if (*this) return f(**this); else return none;. +
  • +
  • + Remarks: The return type of this function + is optional<U>. +
  • +

space

diff --git a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics___optional_values.html b/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics___optional_values.html index 127df4c..42af248 100644 --- a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics___optional_values.html +++ b/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/detailed_semantics___optional_values.html @@ -1495,6 +1495,16 @@ these two (as well as the next one) overloads are replaced with good old const and non-const overloads. +
  • + Example: +
    auto length = [](const string& s){ return s.size(); };
    +optional<string> o1 {}, o2 {"cat"};
    +optional<size_t> os1 = o1.map(length), os2 = o2.map(length);
    +assert ( !os1 ) ;
    +assert ( os2 ) ;
    +assert ( *os2 == 3 ) ;
    +
    +
  • space @@ -1515,6 +1525,72 @@ is optional<decltype(f(istd::move(**this)))>. +

    + space +

    +

    + template<class F> auto optional<T>::flat_map(F f) const& -> + see below ; +

    +

    + template<class F> auto optional<T>::flat_map(F f) & -> see below + ; +

    +
      +
    • + Requires: The return type of expression + f(**this) + is optional<U> + for some object or reference type U. +
    • +
    • + Effects: if + (*this) return f(**this); else return + none; +
    • +
    • + Notes: The return type of these overloads + is optional<U>. + On compilers that do not support ref-qualifiers on member functions, + these two (as well as the next one) overloads are replaced with good + old const and non-const overloads. +
    • +
    • + Example: +
      optional<char> first_char(const string& s) {
      +  return s.empty() ? none : optional<char>(s[0]);
      +};
      +optional<string> o1 {}, o2 {"cat"};
      +optional<char> os1 = o1.flat_map(first_char), os2 = o2.flat_map(first_char);
      +assert ( !os1 ) ;
      +assert ( os2 ) ;
      +assert ( *os2 == 'c' ) ;
      +
      + space +
    • +
    +

    + template<class F> auto optional<T>::flat_map(F f) && + -> see below + ; +

    +
      +
    • + Requires: The return type of expression + f(std::move(**this)) + is optional<U> + for some object or reference type U. +
    • +
    • + Effects: if + (*this) return f(std::move(**this)); else return + none; +
    • +
    • + Notes: The return type of this overload + is optional<U>. +
    • +

    space

    diff --git a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/header_optional_optional_refs.html b/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/header_optional_optional_refs.html index 77906eb..43b0c0a 100644 --- a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/header_optional_optional_refs.html +++ b/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/header_optional_optional_refs.html @@ -53,7 +53,6 @@ optional& operator = ( none_t ) noexcept ; R - optional& operator = ( optional const& rhs ) noexcept; R template<class U> optional& operator = ( optional<U&> const& rhs ) noexcept ; R @@ -75,6 +74,8 @@ template<class F> auto map( F f ) const -> see below; R + template<class F> auto flat_map( F f ) const -> see below; R + T* get_ptr() const noexcept ; R bool has_value() const noexcept ; R diff --git a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/header_optional_optional_values.html b/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/header_optional_optional_values.html index 5e960f1..5e1edff 100644 --- a/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/header_optional_optional_values.html +++ b/doc/html/boost_optional/reference/header__boost_optional_optional_hpp_/header_optional_optional_values.html @@ -109,6 +109,10 @@ template<class F> auto map( F f ) & -> see below; R template<class F> auto map( F f ) && -> see below; R + template<class F> auto flat_map( F f ) const& -> see below; R + template<class F> auto flat_map( F f ) & -> see below; R + template<class F> auto flat_map( F f ) && -> see below; R + T const* get_ptr() const ; R T* get_ptr() ; R diff --git a/doc/html/boost_optional/relnotes.html b/doc/html/boost_optional/relnotes.html index b596e38..f074211 100644 --- a/doc/html/boost_optional/relnotes.html +++ b/doc/html/boost_optional/relnotes.html @@ -37,7 +37,10 @@ #52).
  • - Added member function map() for transforming optional<T> into optional<U> using a function of type U(T). + Added member function map() for transforming optional<T> into optional<U> using a function of type T -> U. +
  • +
  • + Added member function flat_map() for transforming optional<T> into optional<U> using a function of type T -> optonal<U>.
  • diff --git a/doc/html/index.html b/doc/html/index.html index 44e9bc0..c563c86 100644 --- a/doc/html/index.html +++ b/doc/html/index.html @@ -145,7 +145,7 @@ - +

    Last revised: June 23, 2018 at 18:49:36 GMT

    Last revised: July 02, 2018 at 21:10:01 GMT