diff --git a/doc/html/boost_optional/detailed_semantics.html b/doc/html/boost_optional/detailed_semantics.html index 4a5394e..dbfe0cb 100644 --- a/doc/html/boost_optional/detailed_semantics.html +++ b/doc/html/boost_optional/detailed_semantics.html @@ -1200,6 +1200,43 @@ +

+ space +

+

+ T const& optional<T>::value() const ; +

+

+ T& + optional<T>::value(); +

+

space

diff --git a/doc/html/boost_optional/exception_safety_guarantees.html b/doc/html/boost_optional/exception_safety_guarantees.html index eb29f92..4b2b0a5 100644 --- a/doc/html/boost_optional/exception_safety_guarantees.html +++ b/doc/html/boost_optional/exception_safety_guarantees.html @@ -95,8 +95,8 @@

Unless T's constructor or assignment - throws, optional<T> does - not throw anything else on its own. A throw during assignment never changes + 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);
diff --git a/doc/html/boost_optional/synopsis.html b/doc/html/boost_optional/synopsis.html
index 075bfbf..0e2b20e 100644
--- a/doc/html/boost_optional/synopsis.html
+++ b/doc/html/boost_optional/synopsis.html
@@ -90,6 +90,9 @@
     T const& operator *() const ; R
     T&       operator *() ; R
 
+    T const& value() const ; R
+    T&       value() ; R
+
     T const* get_ptr() const ; R
     T*       get_ptr() ; R
 
diff --git a/doc/html/index.html b/doc/html/index.html
index 1bb9006..5c74f5b 100644
--- a/doc/html/index.html
+++ b/doc/html/index.html
@@ -92,7 +92,7 @@
 
 
 
-
+

Last revised: May 08, 2014 at 12:05:10 GMT

Last revised: May 22, 2014 at 21:28:38 GMT


diff --git a/doc/reference.qbk b/doc/reference.qbk index 5cbaf6b..80c6927 100644 --- a/doc/reference.qbk +++ b/doc/reference.qbk @@ -74,6 +74,9 @@ T const& operator *() const ; ``[link reference_optional_get __GO_TO__]`` T& operator *() ; ``[link reference_optional_get __GO_TO__]`` + + T const& value() const ; ``[link reference_optional_value __GO_TO__]`` + T& value() ; ``[link reference_optional_value __GO_TO__]`` T const* get_ptr() const ; ``[link reference_optional_get_ptr __GO_TO__]`` T* get_ptr() ; ``[link reference_optional_get_ptr __GO_TO__]`` @@ -803,6 +806,31 @@ assert ( *opt == w ) ; __SPACE__ + +[#reference_optional_value] + +[: `T const& optional::value() const ;`] +[: `T& optional::value();`] + +* [*Returns:] A reference to the contained value, if `*this` is initialized. +* [*Throws:] An instance of `bad_optional_access`, if `*this` is not initialized. +* [*Example:] +`` +T v ; +optional o0, o1 ( v ); +assert ( o1.value() == v ); + +try { + o0.value(); // throws + assert ( false ); +} +catch(bad_optional_access&) { + asert ( true ); +} +`` + +__SPACE__ + [#reference_optional_get_value_or_value] [: `T const& optional::get_value_or( T const& default) const ;`] diff --git a/doc/special_cases.qbk b/doc/special_cases.qbk index adc191e..6173c16 100644 --- a/doc/special_cases.qbk +++ b/doc/special_cases.qbk @@ -336,7 +336,7 @@ Regarding the following assignment functions: 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`'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`'s assignment also never throws. -Unless `T`'s constructor or assignment throws, `optional` does not throw anything else on its own. A throw during assignment never changes the initialization state of any optional object involved: +Unless `T`'s constructor or assignment throws, assignments to `optional` do not throw anything else on its own. A throw during assignment never changes the initialization state of any optional object involved: optional opt1(val1); diff --git a/include/boost/bad_optional_access.hpp b/include/boost/bad_optional_access.hpp new file mode 100644 index 0000000..95abf3a --- /dev/null +++ b/include/boost/bad_optional_access.hpp @@ -0,0 +1,28 @@ +// Copyright (C) 2014, Andrzej Krzemienski. +// +// Use, modification, and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/optional for documentation. +// +// You are welcome to contact the author at: +// akrzemi1@gmail.com +// +#ifndef BOOST_BAD_OPTIONAL_ACCESS_22MAY2014_HPP +#define BOOST_BAD_OPTIONAL_ACCESS_22MAY2014_HPP + +#include + +namespace boost { + +class bad_optional_access : public std::logic_error +{ +public: + explicit bad_optional_access(const std::string& what_arg) : std::logic_error(what_arg) {} + explicit bad_optional_access(const char* what_arg) : std::logic_error(what_arg) {} +}; + +} // namespace boost + +#endif diff --git a/include/boost/optional/optional.hpp b/include/boost/optional/optional.hpp index d9e8a97..b6ca7e9 100644 --- a/include/boost/optional/optional.hpp +++ b/include/boost/optional/optional.hpp @@ -23,7 +23,9 @@ #include #include +#include #include +#include #include #include #include @@ -935,6 +937,22 @@ class optional : public optional_detail::optional_base // No-throw reference_const_type operator *() const { return this->get() ; } reference_type operator *() { return this->get() ; } + + reference_const_type value() const + { + if (this->is_initialized()) + return this->get() ; + else + throw_exception(bad_optional_access("Attempted to access the value of an uninitialized optional object.")); + } + + reference_type value() + { + if (this->is_initialized()) + return this->get() ; + else + throw_exception(bad_optional_access("Attempted to access the value of an uninitialized optional object.")); + } bool operator!() const BOOST_NOEXCEPT { return !this->is_initialized() ; } diff --git a/include/boost/optional/optional_fwd.hpp b/include/boost/optional/optional_fwd.hpp index 29cee49..fb59682 100644 --- a/include/boost/optional/optional_fwd.hpp +++ b/include/boost/optional/optional_fwd.hpp @@ -11,11 +11,9 @@ // // Revisions: // 10 May 2008 (added swap related forward declaration) Niels Dekker -// 17 Apr 2014 (added noexcept) Andrzej Krzemienski // #ifndef BOOST_OPTIONAL_OPTIONAL_FWD_FLC_19NOV2002_HPP #define BOOST_OPTIONAL_OPTIONAL_FWD_FLC_19NOV2002_HPP -#include namespace boost { diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 7218ffa..10fd597 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -23,6 +23,7 @@ import testing ; [ run optional_test_io.cpp ] [ run optional_test_move.cpp ] [ run optional_test_equals_none.cpp ] + [ run optional_test_value_access.cpp ] [ compile-fail optional_test_fail1.cpp ] [ compile-fail optional_test_fail3a.cpp ] [ compile-fail optional_test_fail3b.cpp ] diff --git a/test/optional_test_value_access.cpp b/test/optional_test_value_access.cpp new file mode 100644 index 0000000..5cff1b7 --- /dev/null +++ b/test/optional_test_value_access.cpp @@ -0,0 +1,107 @@ +// 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 +#include +#include + +#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 +void test_function_value_for() +{ + optional o0; + optional o1(1); + const optional oC(2); + + try + { + T& v = o1.value(); + BOOST_CHECK(v == 1); + } + catch(...) + { + BOOST_CHECK(false); + } + + try + { + T const& v = oC.value(); + BOOST_CHECK(v == 2); + } + catch(...) + { + BOOST_CHECK(false); + } + + try + { + T& v = o0.value(); + BOOST_CHECK(false); + unused_variable(v); + } + catch(boost::bad_optional_access const&) + { + } + catch(...) + { + BOOST_CHECK(false); + } +} + +void test_function_value() +{ + test_function_value_for(); + test_function_value_for(); + test_function_value_for(); +} + +int test_main( int, char* [] ) +{ + try + { + test_function_value(); + + } + catch ( ... ) + { + BOOST_ERROR("Unexpected Exception caught!"); + } + + return 0; +} + +