diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 378a30e..ec7e4cb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,8 @@ jobs: buildtype: "boost" packages: "" packages_to_remove: "" - os: "ubuntu-16.04" + os: "ubuntu-20.04" + container: "ubuntu:16.04" cxx: "g++" sources: "" llvm_os: "" @@ -33,7 +34,8 @@ jobs: buildtype: "boost" packages: "g++-4.7" packages_to_remove: "" - os: "ubuntu-16.04" + os: "ubuntu-20.04" + container: "ubuntu:16.04" cxx: "g++-4.7" sources: "" llvm_os: "" @@ -45,7 +47,8 @@ jobs: buildtype: "boost" packages: "g++-4.8" packages_to_remove: "" - os: "ubuntu-16.04" + os: "ubuntu-20.04" + container: "ubuntu:16.04" cxx: "g++-4.8" sources: "" llvm_os: "" @@ -57,7 +60,8 @@ jobs: buildtype: "boost" packages: "g++-4.9" packages_to_remove: "" - os: "ubuntu-16.04" + os: "ubuntu-20.04" + container: "ubuntu:16.04" cxx: "g++-4.9" sources: "" llvm_os: "" @@ -69,7 +73,8 @@ jobs: buildtype: "boost" packages: "g++-5" packages_to_remove: "" - os: "ubuntu-16.04" + os: "ubuntu-20.04" + container: "ubuntu:16.04" cxx: "g++-5" sources: "" llvm_os: "" @@ -81,7 +86,8 @@ jobs: buildtype: "boost" packages: "g++-6" packages_to_remove: "" - os: "ubuntu-16.04" + os: "ubuntu-20.04" + container: "ubuntu:16.04" cxx: "g++-6" sources: "" llvm_os: "" @@ -93,7 +99,8 @@ jobs: buildtype: "boost" packages: "g++-7" packages_to_remove: "" - os: "ubuntu-16.04" + os: "ubuntu-20.04" + container: "ubuntu:16.04" cxx: "g++-7" sources: "" llvm_os: "" @@ -105,7 +112,7 @@ jobs: buildtype: "boost" packages: "" packages_to_remove: "" - os: "ubuntu-16.04" + os: "ubuntu-18.04" cxx: "clang++" sources: "" llvm_os: "" @@ -117,7 +124,8 @@ jobs: buildtype: "boost" packages: "clang-3.5 libstdc++-4.9-dev" packages_to_remove: "" - os: "ubuntu-16.04" + os: "ubuntu-20.04" + container: "ubuntu:16.04" cxx: "clang++-3.5" sources: "" llvm_os: "precise" @@ -129,7 +137,8 @@ jobs: buildtype: "boost" packages: "clang-3.6" packages_to_remove: "" - os: "ubuntu-16.04" + os: "ubuntu-20.04" + container: "ubuntu:16.04" cxx: "clang++-3.6" sources: "" llvm_os: "precise" @@ -141,7 +150,8 @@ jobs: buildtype: "boost" packages: "clang-3.7" packages_to_remove: "" - os: "ubuntu-16.04" + os: "ubuntu-20.04" + container: "ubuntu:16.04" cxx: "clang++-3.7" sources: "" llvm_os: "precise" @@ -153,7 +163,8 @@ jobs: buildtype: "boost" packages: "clang-3.8 libstdc++-4.9-dev" packages_to_remove: "" - os: "ubuntu-16.04" + os: "ubuntu-20.04" + container: "ubuntu:16.04" cxx: "clang++-3.8" sources: "" llvm_os: "precise" @@ -165,7 +176,8 @@ jobs: buildtype: "boost" packages: "clang-3.9 libstdc++-4.9-dev" packages_to_remove: "" - os: "ubuntu-16.04" + os: "ubuntu-20.04" + container: "ubuntu:16.04" cxx: "clang++-3.9" sources: "" llvm_os: "precise" @@ -177,7 +189,7 @@ jobs: buildtype: "boost" packages: "clang-4.0" packages_to_remove: "" - os: "ubuntu-16.04" + os: "ubuntu-20.04" container: "ubuntu:14.04" cxx: "clang++-4.0" sources: "" @@ -190,7 +202,7 @@ jobs: buildtype: "boost" packages: "clang-5.0" packages_to_remove: "" - os: "ubuntu-16.04" + os: "ubuntu-20.04" container: "ubuntu:14.04" cxx: "clang++-5.0" sources: "" @@ -210,10 +222,12 @@ jobs: - name: If running in container, upgrade packages if: matrix.container != '' run: | - sudo apt-get -o Acquire::Retries=3 update && DEBIAN_FRONTEND=noninteractive apt-get -y install tzdata && apt-get -o Acquire::Retries=3 install -y sudo software-properties-common wget curl apt-transport-https make apt-file sudo unzip libssl-dev build-essential autotools-dev autoconf automake g++ libc++-helpers python python-pip ruby cpio gcc-multilib g++-multilib pkgconf python3 python3-pip ccache libpython-dev + apt-get -o Acquire::Retries=3 update && DEBIAN_FRONTEND=noninteractive apt-get -y install tzdata && apt-get -o Acquire::Retries=3 install -y sudo software-properties-common wget curl apt-transport-https make apt-file sudo unzip libssl-dev build-essential autotools-dev autoconf automake g++ libc++-helpers python ruby cpio gcc-multilib g++-multilib pkgconf python3 ccache libpython-dev sudo apt-add-repository ppa:git-core/ppa sudo apt-get -o Acquire::Retries=3 update && apt-get -o Acquire::Retries=3 -y install git - sudo python -m pip install --upgrade pip==20.3.4 + python_version=$(python3 -c 'import sys; print("{0.major}.{0.minor}".format(sys.version_info))') + sudo wget https://bootstrap.pypa.io/pip/$python_version/get-pip.py + sudo python3 get-pip.py sudo /usr/local/bin/pip install cmake - uses: actions/checkout@v2 diff --git a/CMakeLists.txt b/CMakeLists.txt index 3c836a4..f60acf5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,12 +1,9 @@ # Copyright 2019 Mike Dev # Distributed under the Boost Software License, Version 1.0. # See accompanying file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt -# -# NOTE: CMake support for Boost.Optional is currently experimental at best -# and the interface is likely to change in the future -cmake_minimum_required( VERSION 3.5 ) -project( BoostOptional ) +cmake_minimum_required( VERSION 3.5...3.20 ) +project( boost_optional VERSION "${BOOST_SUPERPROJECT_VERSION}" LANGUAGES CXX ) add_library( boost_optional INTERFACE ) add_library( Boost::optional ALIAS boost_optional ) diff --git a/doc/17_gotchas.qbk b/doc/17_gotchas.qbk index 5cfa36b..5e5926e 100644 --- a/doc/17_gotchas.qbk +++ b/doc/17_gotchas.qbk @@ -61,12 +61,12 @@ When an optional object that contains a value is moved from (is a source of move assert (opi); assert (*opi == nullptr); -Quite a lot of people expect that when an object that contains a value is moved from, its contained value should be destroyed. This is not so, for performance reasons. Current semantics allow the implementation of `boost::opiotnal` to be trivially copyable when `T` is trivial. +Quite a lot of people expect that when an object that contains a value is moved from, its contained value should be destroyed. This is not so, for performance reasons. Current semantics allow the implementation of `boost::optional` to be trivially copyable when `T` is trivial. [endsect] [section Mixed relational comparisons] -Because `T` is convertible to `optional` and because `opiotnal` is __SGI_LESS_THAN_COMPARABLE__ when `T` is __SGI_LESS_THAN_COMPARABLE__, +Because `T` is convertible to `optional` and because `optional` is __SGI_LESS_THAN_COMPARABLE__ when `T` is __SGI_LESS_THAN_COMPARABLE__, you can sometimes get an unexpected runtime result where you would rather expect a compiler error: optional Flight_plan::weight(); // sometimes no weight can be returned @@ -108,4 +108,4 @@ This is obviously redundant, but makes the warning disappear. [endsect] -[endsect] \ No newline at end of file +[endsect] diff --git a/doc/91_relnotes.qbk b/doc/91_relnotes.qbk index 2f4b834..48e59f5 100644 --- a/doc/91_relnotes.qbk +++ b/doc/91_relnotes.qbk @@ -1,7 +1,7 @@ [/ Boost.Optional - Copyright (c) 2015 - 2018 Andrzej Krzemienski + Copyright (c) 2015 - 2021 Andrzej Krzemienski Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -11,6 +11,14 @@ [section:relnotes Release Notes] +[heading Boost Release 1.79] + +* Fixed [@https://github.com/boostorg/optional/issues/98 issue #98]. + +[heading Boost Release 1.77] + +* Fixed [@https://github.com/boostorg/optional/issues/92 issue #92]. + [heading Boost Release 1.76] * Fixed MSVC warning C4702. diff --git a/doc/html/boost_optional/relnotes.html b/doc/html/boost_optional/relnotes.html index 7113051..fc6c8e9 100644 --- a/doc/html/boost_optional/relnotes.html +++ b/doc/html/boost_optional/relnotes.html @@ -28,6 +28,24 @@

+ Boost + Release 1.79 +

+
+

+ + Boost + Release 1.77 +

+
+

+ Boost Release 1.76

@@ -35,7 +53,7 @@ Fixed MSVC warning C4702.

- + Boost Release 1.75

@@ -49,7 +67,7 @@

- + Boost Release 1.73

@@ -72,7 +90,7 @@

- + Boost Release 1.69

@@ -90,7 +108,7 @@

- + Boost Release 1.68

@@ -107,7 +125,7 @@

- + Boost Release 1.67

@@ -121,7 +139,7 @@

- + Boost Release 1.66

@@ -139,7 +157,7 @@

- + Boost Release 1.63

@@ -163,7 +181,7 @@

- + Boost Release 1.62

@@ -171,7 +189,7 @@ Fixed Trac #12179.

- + Boost Release 1.61

@@ -214,7 +232,7 @@

- + Boost Release 1.60

@@ -225,7 +243,7 @@ #11203.

- + Boost Release 1.59

@@ -239,7 +257,7 @@

- + Boost Release 1.58

@@ -275,7 +293,7 @@

- + Boost Release 1.57

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

- + Boost Release 1.56

diff --git a/doc/html/index.html b/doc/html/index.html index 56f5f86..08105c5 100644 --- a/doc/html/index.html +++ b/doc/html/index.html @@ -145,7 +145,7 @@ - +

Last revised: March 10, 2021 at 22:06:01 GMT

Last revised: November 20, 2021 at 00:57:52 GMT


diff --git a/include/boost/optional/detail/optional_aligned_storage.hpp b/include/boost/optional/detail/optional_aligned_storage.hpp index 2937349..b290921 100644 --- a/include/boost/optional/detail/optional_aligned_storage.hpp +++ b/include/boost/optional/detail/optional_aligned_storage.hpp @@ -28,7 +28,7 @@ class aligned_storage // BOOST_MAY_ALIAS works around GCC warnings about breaking strict aliasing rules when casting storage address to T* union BOOST_MAY_ALIAS dummy_u { - char data[ sizeof(T) ]; + unsigned char data[ sizeof(T) ]; BOOST_DEDUCED_TYPENAME type_with_alignment< ::boost::alignment_of::value >::type aligner_; } dummy_ ; diff --git a/include/boost/optional/detail/optional_trivially_copyable_base.hpp b/include/boost/optional/detail/optional_trivially_copyable_base.hpp index 2cabf9a..5a5b80b 100644 --- a/include/boost/optional/detail/optional_trivially_copyable_base.hpp +++ b/include/boost/optional/detail/optional_trivially_copyable_base.hpp @@ -1,3 +1,14 @@ +// Copyright (C) 2017 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 + // trivilally-copyable version of the storage template @@ -69,7 +80,7 @@ class tc_optional_base : public optional_tag // ~tc_optional_base() = default; // Assigns from another optional (deep-copies the rhs value) - void assign ( tc_optional_base const& rhs ) + void assign ( tc_optional_base const& rhs ) { *this = rhs; } @@ -84,7 +95,7 @@ class tc_optional_base : public optional_tag #else m_storage = static_cast(rhs.get()); #endif - + m_initialized = rhs.is_initialized(); } @@ -99,7 +110,7 @@ class tc_optional_base : public optional_tag m_initialized = rhs.is_initialized(); } #endif - + void assign ( argument_type val ) { construct(val); @@ -166,7 +177,7 @@ class tc_optional_base : public optional_tag { construct(in_place_init, boost::forward(args)...); } - + template explicit tc_optional_base ( in_place_init_t, Args&&... args ) : @@ -174,7 +185,7 @@ class tc_optional_base : public optional_tag { construct(in_place_init, boost::forward(args)...); } - + template explicit tc_optional_base ( in_place_init_if_t, bool cond, Args&&... args ) : @@ -190,24 +201,24 @@ class tc_optional_base : public optional_tag m_storage = value_type( boost::forward(arg) ); m_initialized = true ; } - + void construct ( in_place_init_t ) { m_storage = value_type(); m_initialized = true ; } - + template void emplace_assign ( Arg&& arg ) { construct(in_place_init, boost::forward(arg)) ; } - + void emplace_assign () { construct(in_place_init) ; } - + template explicit tc_optional_base ( in_place_init_t, Arg&& arg ) : @@ -215,11 +226,11 @@ class tc_optional_base : public optional_tag { construct(in_place_init, boost::forward(arg)); } - + explicit tc_optional_base ( in_place_init_t ) : m_initialized(false), m_storage() {} - + template explicit tc_optional_base ( in_place_init_if_t, bool cond, Arg&& arg ) : @@ -228,7 +239,7 @@ class tc_optional_base : public optional_tag if ( cond ) construct(in_place_init, boost::forward(arg)); } - + explicit tc_optional_base ( in_place_init_if_t, bool cond ) : m_initialized(false) @@ -238,21 +249,21 @@ class tc_optional_base : public optional_tag } #else - + template void construct ( in_place_init_t, const Arg& arg ) { m_storage = value_type( arg ); m_initialized = true ; } - + template void construct ( in_place_init_t, Arg& arg ) { m_storage = value_type( arg ); m_initialized = true ; } - + void construct ( in_place_init_t ) { m_storage = value_type(); @@ -264,18 +275,18 @@ class tc_optional_base : public optional_tag { construct(in_place_init, arg); } - + template void emplace_assign ( Arg& arg ) { construct(in_place_init, arg); } - + void emplace_assign () { construct(in_place_init); } - + template explicit tc_optional_base ( in_place_init_t, const Arg& arg ) : m_initialized(false) @@ -289,13 +300,13 @@ class tc_optional_base : public optional_tag { construct(in_place_init, arg); } - + explicit tc_optional_base ( in_place_init_t ) : m_initialized(false) { construct(in_place_init); } - + template explicit tc_optional_base ( in_place_init_if_t, bool cond, const Arg& arg ) : m_initialized(false) @@ -303,15 +314,15 @@ class tc_optional_base : public optional_tag if ( cond ) construct(in_place_init, arg); } - + template explicit tc_optional_base ( in_place_init_if_t, bool cond, Arg& arg ) : m_initialized(false) { if ( cond ) construct(in_place_init, arg); - } - + } + explicit tc_optional_base ( in_place_init_if_t, bool cond ) : m_initialized(false) { diff --git a/include/boost/optional/optional.hpp b/include/boost/optional/optional.hpp index aadc975..a04ac86 100644 --- a/include/boost/optional/optional.hpp +++ b/include/boost/optional/optional.hpp @@ -1,5 +1,5 @@ // Copyright (C) 2003, 2008 Fernando Luis Cacciola Carballal. -// Copyright (C) 2014 - 2018 Andrzej Krzemienski. +// Copyright (C) 2014 - 2021 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 @@ -18,7 +18,9 @@ #define BOOST_OPTIONAL_OPTIONAL_FLC_19NOV2002_HPP #include +#ifndef BOOST_NO_IOSTREAM #include +#endif // BOOST_NO_IOSTREAM #ifdef BOOST_OPTIONAL_DETAIL_USE_STD_TYPE_TRAITS # include @@ -35,14 +37,18 @@ #include #include #include +#include +#include #include #include #include #include #include +#include #include #include #include +#include #include #include #include @@ -123,6 +129,7 @@ class optional_base : public optional_tag protected : typedef T value_type ; + typedef typename boost::remove_const::type unqualified_value_type; protected: typedef T & reference_type ; @@ -399,14 +406,14 @@ class optional_base : public optional_tag void construct ( argument_type val ) { - ::new (m_storage.address()) value_type(val) ; + ::new (m_storage.address()) unqualified_value_type(val) ; m_initialized = true ; } #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES void construct ( rval_reference_type val ) { - ::new (m_storage.address()) value_type( boost::move(val) ) ; + ::new (m_storage.address()) unqualified_value_type( boost::move(val) ) ; m_initialized = true ; } #endif @@ -418,7 +425,7 @@ class optional_base : public optional_tag template void construct ( in_place_init_t, Args&&... args ) { - ::new (m_storage.address()) value_type( boost::forward(args)... ) ; + ::new (m_storage.address()) unqualified_value_type( boost::forward(args)... ) ; m_initialized = true ; } @@ -449,13 +456,13 @@ class optional_base : public optional_tag template void construct ( in_place_init_t, Arg&& arg ) { - ::new (m_storage.address()) value_type( boost::forward(arg) ); + ::new (m_storage.address()) unqualified_value_type( boost::forward(arg) ); m_initialized = true ; } void construct ( in_place_init_t ) { - ::new (m_storage.address()) value_type(); + ::new (m_storage.address()) unqualified_value_type(); m_initialized = true ; } @@ -509,20 +516,20 @@ class optional_base : public optional_tag template void construct ( in_place_init_t, const Arg& arg ) { - ::new (m_storage.address()) value_type( arg ); + ::new (m_storage.address()) unqualified_value_type( arg ); m_initialized = true ; } template void construct ( in_place_init_t, Arg& arg ) { - ::new (m_storage.address()) value_type( arg ); + ::new (m_storage.address()) unqualified_value_type( arg ); m_initialized = true ; } void construct ( in_place_init_t ) { - ::new (m_storage.address()) value_type(); + ::new (m_storage.address()) unqualified_value_type(); m_initialized = true ; } @@ -667,7 +674,7 @@ class optional_base : public optional_tag template void construct ( Expr&& expr, void const* ) { - new (m_storage.address()) value_type(boost::forward(expr)) ; + new (m_storage.address()) unqualified_value_type(boost::forward(expr)) ; m_initialized = true ; } @@ -688,7 +695,7 @@ class optional_base : public optional_tag template void construct ( Expr const& expr, void const* ) { - new (m_storage.address()) value_type(expr) ; + new (m_storage.address()) unqualified_value_type(expr) ; m_initialized = true ; } @@ -726,7 +733,7 @@ class optional_base : public optional_tag { // An exception can be thrown here. // It it happens, THIS will be left uninitialized. - new (m_storage.address()) value_type(boost::move(expr.get())) ; + new (m_storage.address()) unqualified_value_type(boost::move(expr.get())) ; m_initialized = true ; } } @@ -739,7 +746,7 @@ class optional_base : public optional_tag { // An exception can be thrown here. // It it happens, THIS will be left uninitialized. - new (m_storage.address()) value_type(expr.get()) ; + new (m_storage.address()) unqualified_value_type(expr.get()) ; m_initialized = true ; } } @@ -779,7 +786,7 @@ class optional_base : public optional_tag // definition of metafunction is_optional_val_init_candidate template -struct is_optional_related +struct is_optional_or_tag : boost::conditional< boost::is_base_of::type>::value || boost::is_same::type, none_t>::value || boost::is_same::type, in_place_init_t>::value @@ -787,14 +794,22 @@ struct is_optional_related boost::true_type, boost::false_type>::type {}; +template +struct has_dedicated_constructor + : boost::disjunction, boost::is_same::type> > +{}; + +template +struct is_in_place_factory + : boost::disjunction< boost::is_base_of::type>, + boost::is_base_of::type> > +{}; + #if !defined(BOOST_OPTIONAL_DETAIL_NO_IS_CONSTRUCTIBLE_TRAIT) template -struct is_convertible_to_T_or_factory - : boost::conditional< boost::is_base_of::type>::value - || boost::is_base_of::type>::value - || (boost::is_constructible::value && !boost::is_same::type>::value) - , boost::true_type, boost::false_type>::type +struct is_factory_or_constructible_to_T + : boost::disjunction< is_in_place_factory, boost::is_constructible > {}; template @@ -804,7 +819,7 @@ struct is_optional_constructible : boost::is_constructible #else template -struct is_convertible_to_T_or_factory : boost::true_type +struct is_factory_or_constructible_to_T : boost::true_type {}; template @@ -813,15 +828,58 @@ struct is_optional_constructible : boost::true_type #endif // is_convertible condition -template ::value> +#if !defined(BOOST_NO_CXX11_DECLTYPE) && !BOOST_WORKAROUND(BOOST_MSVC, < 1800) +// for is_assignable + +#if (!defined BOOST_NO_CXX11_RVALUE_REFERENCES) +// On some initial rvalue reference implementations GCC does it in a strange way, +// preferring perfect-forwarding constructor to implicit copy constructor. + +template +struct is_opt_assignable + : boost::conjunction, boost::is_assignable > +{}; + +#else + +template +struct is_opt_assignable + : boost::conjunction, boost::is_assignable > +{}; + +#endif + +#else + +template +struct is_opt_assignable : boost::is_convertible +{}; + +#endif + +template +struct is_factory_or_opt_assignable_to_T + : boost::disjunction< is_in_place_factory, is_opt_assignable > +{}; + +template ::value> struct is_optional_val_init_candidate : boost::false_type {}; template struct is_optional_val_init_candidate - : boost::conditional< is_convertible_to_T_or_factory::value - , boost::true_type, boost::false_type>::type + : is_factory_or_constructible_to_T +{}; + +template ::value> +struct is_optional_val_assign_candidate + : boost::false_type +{}; + +template +struct is_optional_val_assign_candidate + : is_factory_or_opt_assignable_to_T {}; } // namespace optional_detail @@ -994,7 +1052,7 @@ class optional #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES template - BOOST_DEDUCED_TYPENAME boost::enable_if, optional&>::type + BOOST_DEDUCED_TYPENAME boost::enable_if, optional&>::type operator= ( Expr&& expr ) { this->assign_expr(boost::forward(expr),boost::addressof(expr)); @@ -1586,6 +1644,7 @@ get_pointer ( optional& opt ) } // namespace boost +#ifndef BOOST_NO_IOSTREAM namespace boost { // The following declaration prevents a bug where operator safe-bool is used upon streaming optional object if you forget the IO header. @@ -1598,6 +1657,7 @@ operator<<(std::basic_ostream& os, optional_detail::optiona } } // namespace boost +#endif // BOOST_NO_IOSTREAM #include #include diff --git a/include/boost/optional/optional_io.hpp b/include/boost/optional/optional_io.hpp index ce81b68..3db6dda 100644 --- a/include/boost/optional/optional_io.hpp +++ b/include/boost/optional/optional_io.hpp @@ -12,6 +12,7 @@ #ifndef BOOST_OPTIONAL_OPTIONAL_IO_FLC_19NOV2002_HPP #define BOOST_OPTIONAL_OPTIONAL_IO_FLC_19NOV2002_HPP +#ifndef BOOST_NO_IOSTREAM #include #include @@ -31,7 +32,7 @@ operator<<(std::basic_ostream& out, none_t) { out << "--"; } - + return out; } @@ -90,5 +91,5 @@ operator>>(std::basic_istream& in, optional& v) } // namespace boost +#endif // BOOST_NO_IOSTREAM #endif - diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index a881d52..477f4df 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -22,6 +22,7 @@ import testing ; [ run optional_test_swap.cpp ] [ run optional_test_conversions_from_U.cpp ] [ run optional_test_convert_from_T.cpp ] + [ run optional_test_convert_assign.cpp ] [ run optional_test_empty_braces.cpp ] [ run optional_test_make_optional.cpp ] [ run optional_test_flat_map.cpp ] diff --git a/test/optional_test.cpp b/test/optional_test.cpp index a0fa5a6..f5ca436 100644 --- a/test/optional_test.cpp +++ b/test/optional_test.cpp @@ -12,7 +12,9 @@ // Revisions: // 12 May 2008 (added more swap tests) // +#ifndef BOOST_NO_IOSTREAM #include +#endif // BOOST_NO_IOSTREAM #include #include @@ -908,7 +910,7 @@ void test_no_implicit_conversions() // Test for support for classes with overridden operator& -class CustomAddressOfClass +class CustomAddressOfClass { int n; @@ -950,5 +952,3 @@ int main() return boost::report_errors(); } - - diff --git a/test/optional_test_convert_assign.cpp b/test/optional_test_convert_assign.cpp new file mode 100644 index 0000000..f0366dc --- /dev/null +++ b/test/optional_test_convert_assign.cpp @@ -0,0 +1,57 @@ +// Copyright (C) 2021 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" + +#include "boost/core/lightweight_test.hpp" +#include "boost/none.hpp" + +//#ifndef BOOST_OPTIONAL_NO_CONVERTING_COPY_CTOR + +using boost::optional; + +struct implicit_bool_conv +{ + operator bool() const { return false; } +}; + +struct explicit_bool_conv +{ + bool operator!() const BOOST_NOEXCEPT { return false; } + BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT() +}; + +template +void test_convert_assign() +{ + optional oi; + oi = From(); + BOOST_TEST(oi); +} + +void test_no_bad_assignment() +{ +#if !defined(BOOST_NO_CXX11_DECLTYPE) && !BOOST_WORKAROUND(BOOST_MSVC, < 1800) + // this means that type trait `boost::is_assignable` works. + BOOST_STATIC_ASSERT((boost::is_assignable&, bool>::value)); + BOOST_STATIC_ASSERT((boost::is_assignable&, implicit_bool_conv>::value)); + BOOST_STATIC_ASSERT((! boost::is_assignable&, explicit_bool_conv>::value)); +#endif +} + +int main() +{ + test_convert_assign(); + test_convert_assign(); + test_no_bad_assignment(); + + return boost::report_errors(); +} diff --git a/test/optional_test_io.cpp b/test/optional_test_io.cpp index 14c2b26..8086c11 100644 --- a/test/optional_test_io.cpp +++ b/test/optional_test_io.cpp @@ -10,15 +10,19 @@ // You are welcome to contact the author at: // fernando_cacciola@hotmail.com -#include #include "boost/optional/optional.hpp" #include "boost/optional/optional_io.hpp" +#include "boost/core/lightweight_test.hpp" + +#ifndef BOOST_NO_IOSTREAM + +#include #ifdef BOOST_BORLANDC #pragma hdrstop #endif -#include "boost/core/lightweight_test.hpp" + using boost::optional; @@ -29,7 +33,7 @@ void test2( Opt o, Opt buff ) const int markv = 123 ; int mark = 0 ; - + s << o << " " << markv ; s >> buff >> mark ; @@ -85,3 +89,12 @@ int main() return boost::report_errors(); } + +#else // BOOST_NO_IOSTREAM + +int main() +{ + return boost::report_errors(); +} + +#endif // BOOST_NO_IOSTREAM