diff --git a/doc/90_dependencies.qbk b/doc/90_dependencies.qbk index d383905c..0dab296e 100644 --- a/doc/90_dependencies.qbk +++ b/doc/90_dependencies.qbk @@ -17,7 +17,6 @@ The implementation uses the following other Boost modules: # assert # config # core -# detail # move # mpl # static_assert @@ -34,15 +33,15 @@ Certain constructors and functions in the interface of `optional` perform a 'per template optional(in_place_init_t, Args&&... args); template optional(in_place_init_if_t, bool condition, Args&&... args); template void emplace(Args&&... args); - + On compilers that do not support variadic templates, each of these functions is substituted with two overloads, one forwarding a single argument, the other forwarding zero arguments. This forms the following set: template optional(in_place_init_t, Arg&& arg); optional(in_place_init_t); - + template optional(in_place_init_if_t, bool condition, Arg&& arg); optional(in_place_init_if_t, bool condition); - + template void emplace(Arg&& arg); void emplace(); @@ -51,16 +50,16 @@ On compilers that do not support rvalue references, each of these functions is s template optional(in_place_init_t, const Arg& arg); template optional(in_place_init_t, Arg& arg); optional(in_place_init_t); - + template optional(in_place_init_if_t, bool condition, const Arg& arg); template optional(in_place_init_if_t, bool condition, Arg& arg); optional(in_place_init_if_t, bool condition); - + template void emplace(const Arg& arg); template void emplace(Arg& arg); void emplace(); -This workaround addresses about 40% of all use cases. If this is insufficient, you need to resort to using [link boost_optional.tutorial.in_place_factories In-Place Factories]. +This workaround addresses about 40% of all use cases. If this is insufficient, you need to resort to using [link boost_optional.tutorial.in_place_factories In-Place Factories]. [endsect] [section Optional Reference Binding][#optional_reference_binding] @@ -71,11 +70,11 @@ A number of compilers incorrectly treat const lvalues of integral type as rvalue optional or1; optional or2 = i; // caution: not portable or1 = i; // caution: not portable - + optional or3(i); // portable or1 = optional(i); // portable -Compilers known to have these deficiencies include GCC versions 4.2, 4.3, 4.4, 4.5, 5.1, 5.2; QCC 4.4.2; MSVC versions 8.0, 9.0, 10.0, 11.0, 12.0. In order to check if your compiler correctly implements reference binding use this test program. +Compilers known to have these deficiencies include GCC versions 4.2, 4.3, 4.4, 4.5, 5.1, 5.2; QCC 4.4.2; MSVC versions 8.0, 9.0, 10.0, 11.0, 12.0. In order to check if your compiler correctly implements reference binding use this test program. #include @@ -88,13 +87,13 @@ Compilers known to have these deficiencies include GCC versions 4.2, 4.3, 4.4, 4 assert(&ii == &global_i); } - void operator=(const int& ii) + void operator=(const int& ii) { assert(&ii == &global_i); } void operator=(int&&) // remove this if your compiler doesn't have rvalue refs - { + { assert(false); } }; @@ -110,7 +109,7 @@ Compilers known to have these deficiencies include GCC versions 4.2, 4.3, 4.4, 4 TestingReferenceBinding ttt2 = iref; ttt2 = iref; } - + [endsect] -[endsect] \ No newline at end of file +[endsect] diff --git a/doc/91_relnotes.qbk b/doc/91_relnotes.qbk index 8105455d..cadccbec 100644 --- a/doc/91_relnotes.qbk +++ b/doc/91_relnotes.qbk @@ -15,6 +15,7 @@ * Fixed the implementation for trivial types. Now it is slower, because it always initializes the `T`, but it avoids undefined behavior when `optional` is copied. This fixes [@https://github.com/boostorg/optional/issues/108 issue #108]. * Fixed some `-Wmaybe-uninitialized` warnings in GCC 12. Thanks to Christian Mazakas for the fix. +* Dropped dependency on Boost.Detail. [heading Boost Release 1.83] diff --git a/include/boost/optional/detail/experimental_traits.hpp b/include/boost/optional/detail/experimental_traits.hpp index b51f5f10..56670346 100644 --- a/include/boost/optional/detail/experimental_traits.hpp +++ b/include/boost/optional/detail/experimental_traits.hpp @@ -13,10 +13,10 @@ #define BOOST_OPTIONAL_DETAIL_EXPERIMENTAL_TRAITS_04NOV2017_HPP #include -#include +#include #include #include - + // The condition to use POD implementation #ifdef BOOST_OPTIONAL_CONFIG_NO_POD_SPEC @@ -50,7 +50,7 @@ # define BOOST_OPTIONAL_DETAIL_USE_STD_TYPE_TRAITS # endif # endif -#endif +#endif #ifndef BOOST_OPTIONAL_DETAIL_USE_STD_TYPE_TRAITS @@ -59,10 +59,10 @@ # 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 struct is_type_trivially_copyable @@ -83,7 +83,7 @@ struct is_type_trivially_copyable -#ifndef BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES +#ifndef BOOST_OPTIONAL_DETAIL_NO_SPEC_FOR_TRIVIAL_TYPES template struct optional_uses_direct_storage_for_ : boost::conditional< (is_type_trivially_copyable::value && BOOST_OPTIONAL_DETAIL_HAS_TRIVIAL_CTOR(T)) || diff --git a/include/boost/optional/detail/optional_config.hpp b/include/boost/optional/detail/optional_config.hpp index b5040a47..3e5e282f 100644 --- a/include/boost/optional/detail/optional_config.hpp +++ b/include/boost/optional/detail/optional_config.hpp @@ -14,7 +14,7 @@ #define BOOST_OPTIONAL_DETAIL_OPTIONAL_CONFIG_AJK_28JAN2015_HPP #include -#include +#include #if (defined BOOST_NO_CXX11_RVALUE_REFERENCES) || (defined BOOST_OPTIONAL_CONFIG_NO_RVALUE_REFERENCES) # define BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES @@ -55,7 +55,7 @@ #if (defined(_MSC_VER) && _MSC_VER <= 1800) // on MSVC 2013 and earlier an unwanted temporary is created when you assign from // a const lvalue of integral type. Thus we bind not to the original address but -// to a temporary. +// to a temporary. # define BOOST_OPTIONAL_CONFIG_NO_PROPER_ASSIGN_FROM_CONST_INT #endif diff --git a/include/boost/optional/optional.hpp b/include/boost/optional/optional.hpp index 2a183c54..99245ff4 100644 --- a/include/boost/optional/optional.hpp +++ b/include/boost/optional/optional.hpp @@ -83,9 +83,6 @@ struct optional_value_type< ::boost::optional > }} // namespace boost::optional_detail -#ifdef BOOST_OPTIONAL_CONFIG_USE_OLD_IMPLEMENTATION_OF_OPTIONAL -#include -#else namespace boost { namespace optional_ns { @@ -1513,11 +1510,6 @@ class optional BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT() } ; -} // namespace boost - -#endif // BOOST_OPTIONAL_CONFIG_USE_OLD_IMPLEMENTATION_OF_OPTIONAL - -namespace boost { #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES template diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index c5e68bbf..1906eb49 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -44,7 +44,6 @@ import testing ; [ run optional_test_io.cpp ] [ run optional_test_move.cpp ] [ run optional_test_noexcept_move.cpp ] - [ run optional_test_old_impl.cpp ] [ run optional_test_equals_none.cpp ] [ run optional_test_value_access.cpp ] [ run optional_test_emplace.cpp ] diff --git a/test/optional_test.cpp b/test/optional_test.cpp index 5ec00162..81375b8d 100644 --- a/test/optional_test.cpp +++ b/test/optional_test.cpp @@ -849,6 +849,8 @@ struct VBase : virtual X VBase(int v) : X(v) {} // MSVC 8.0 doesn't generate this correctly... VBase(const VBase& other) : X(static_cast(other)) {} + + VBase& operator=(VBase const& rhs) { X::operator=(rhs); return *this; } }; void test_with_class_type() @@ -917,6 +919,7 @@ class CustomAddressOfClass public: CustomAddressOfClass() : n(0) {} CustomAddressOfClass(CustomAddressOfClass const& that) : n(that.n) {} + CustomAddressOfClass& operator=(CustomAddressOfClass const& rhs) { n = rhs.n; return *this; } explicit CustomAddressOfClass(int m) : n(m) {} int* operator& () { return &n; } bool operator== (CustomAddressOfClass const& that) const { return n == that.n; } diff --git a/test/optional_test_old_impl.cpp b/test/optional_test_old_impl.cpp deleted file mode 100644 index f3da56e1..00000000 --- a/test/optional_test_old_impl.cpp +++ /dev/null @@ -1,223 +0,0 @@ -// Copyright (C) 2014 - 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 - -#define BOOST_OPTIONAL_CONFIG_USE_OLD_IMPLEMENTATION_OF_OPTIONAL // does old implementation still work for basic usage? -#include "boost/optional/optional.hpp" - -#ifdef BOOST_BORLANDC -#pragma hdrstop -#endif - -#include "boost/core/ignore_unused.hpp" -#include "boost/core/lightweight_test.hpp" - -using boost::optional; - -struct IntWrapper -{ - int _i; - IntWrapper(int i) : _i(i) {} - bool operator==(IntWrapper const& rhs) const { return _i == rhs._i; } -}; - -template -void test_function_value_or_for() -{ - optional oM0; - const optional oC0; - optional oM1(1); - const optional oC2(2); - - BOOST_TEST(oM0.value_or(5) == 5); - BOOST_TEST(oC0.value_or(5) == 5); - BOOST_TEST(oM1.value_or(5) == 1); - BOOST_TEST(oC2.value_or(5) == 2); -} - -template -void test_function_value_for() -{ - optional o0; - optional o1(1); - const optional oC(2); - - try - { - T& v = o1.value(); - BOOST_TEST(v == 1); - } - catch(...) - { - BOOST_TEST(false); - } - - try - { - T const& v = oC.value(); - BOOST_TEST(v == 2); - } - catch(...) - { - BOOST_TEST(false); - } - - BOOST_TEST_THROWS(o0.value(), boost::bad_optional_access); -} - -void test_function_value() -{ - test_function_value_for(); - test_function_value_for(); - test_function_value_for(); -} - -struct FatToIntConverter -{ - static int conversions; - int _val; - FatToIntConverter(int val) : _val(val) {} - operator int() const { conversions += 1; return _val; } -}; - -int FatToIntConverter::conversions = 0; - -void test_function_value_or() -{ - test_function_value_or_for(); - test_function_value_or_for(); - test_function_value_or_for(); - - optional oi(1); - BOOST_TEST(oi.value_or(FatToIntConverter(2)) == 1); - BOOST_TEST(FatToIntConverter::conversions == 0); - - oi = boost::none; - BOOST_TEST(oi.value_or(FatToIntConverter(2)) == 2); - BOOST_TEST(FatToIntConverter::conversions == 1); -} - - -struct FunM -{ - int operator()() { return 5; } -}; - -struct FunC -{ - int operator()() const { return 6; } -}; - -int funP () -{ - return 7; -} - -int throw_() -{ - throw int(); -} - -void test_function_value_or_eval() -{ - optional o1 = 1; - optional oN; - FunM funM; - FunC funC; - - BOOST_TEST_EQ(o1.value_or_eval(funM), 1); - BOOST_TEST_EQ(oN.value_or_eval(funM), 5); - BOOST_TEST_EQ(o1.value_or_eval(FunM()), 1); - BOOST_TEST_EQ(oN.value_or_eval(FunM()), 5); - - BOOST_TEST_EQ(o1.value_or_eval(funC), 1); - BOOST_TEST_EQ(oN.value_or_eval(funC), 6); - BOOST_TEST_EQ(o1.value_or_eval(FunC()), 1); - BOOST_TEST_EQ(oN.value_or_eval(FunC()), 6); - - BOOST_TEST_EQ(o1.value_or_eval(funP), 1); - BOOST_TEST_EQ(oN.value_or_eval(funP), 7); - -#ifndef BOOST_NO_CXX11_LAMBDAS - BOOST_TEST_EQ(o1.value_or_eval([](){return 8;}), 1); - BOOST_TEST_EQ(oN.value_or_eval([](){return 8;}), 8); -#endif - - try - { - BOOST_TEST_EQ(o1.value_or_eval(throw_), 1); - } - catch(...) - { - BOOST_TEST(false); - } - - BOOST_TEST_THROWS(oN.value_or_eval(throw_), int); -} - -const optional makeConstOptVal() -{ - return std::string("something"); -} - -void test_const_move() -{ - std::string s5 = *makeConstOptVal(); - std::string s6 = makeConstOptVal().value(); - boost::ignore_unused(s5); - boost::ignore_unused(s6); -} - - -#if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) -struct MoveOnly -{ - explicit MoveOnly(int){} - MoveOnly(MoveOnly &&){} - void operator=(MoveOnly &&); -private: - MoveOnly(MoveOnly const&); - void operator=(MoveOnly const&); -}; - -optional makeMoveOnly() -{ - return MoveOnly(1); -} - -MoveOnly moveOnlyDefault() -{ - return MoveOnly(1); -} - -// compile-time test -void test_move_only_getters() -{ - MoveOnly m1 = *makeMoveOnly(); - MoveOnly m2 = makeMoveOnly().value(); - MoveOnly m3 = makeMoveOnly().value_or(MoveOnly(1)); - MoveOnly m4 = makeMoveOnly().value_or_eval(moveOnlyDefault); - boost::ignore_unused(m1); - boost::ignore_unused(m2); - boost::ignore_unused(m3); - boost::ignore_unused(m4); -} - -#endif // !defined BOOST_NO_CXX11_REF_QUALIFIERS - -int main() -{ - test_function_value(); - test_function_value_or(); - test_function_value_or_eval(); - test_const_move(); - - return boost::report_errors(); -} diff --git a/test/optional_test_swap.cpp b/test/optional_test_swap.cpp index 2294c703..d997ef6c 100644 --- a/test/optional_test_swap.cpp +++ b/test/optional_test_swap.cpp @@ -53,6 +53,9 @@ namespace optional_swap_test throw assignment_exception(); } + base_class_with_forbidden_assignment() {} + base_class_with_forbidden_assignment(base_class_with_forbidden_assignment const&) {} + virtual ~base_class_with_forbidden_assignment() {} }; @@ -94,7 +97,8 @@ namespace optional_swap_test class_whose_default_ctor_should_be_used() : data('\0') { } - class_whose_default_ctor_should_be_used(const class_whose_default_ctor_should_be_used &) + class_whose_default_ctor_should_be_used(const class_whose_default_ctor_should_be_used & rhs) + : base_class_with_forbidden_assignment(rhs) { BOOST_TEST(!"This copy constructor should not be used while swapping!"); throw copy_ctor_exception(); @@ -137,7 +141,8 @@ namespace optional_swap_test throw default_ctor_exception(); } - class_whose_explicit_ctor_should_be_used(const class_whose_explicit_ctor_should_be_used &) + class_whose_explicit_ctor_should_be_used(const class_whose_explicit_ctor_should_be_used & rhs) + : base_class_with_forbidden_assignment(rhs) { BOOST_TEST(!"This copy constructor should not be used while swapping!"); throw copy_ctor_exception(); diff --git a/test/optional_test_wuninitialized.cpp b/test/optional_test_wuninitialized.cpp index 2e6bf2ca..9249c31a 100644 --- a/test/optional_test_wuninitialized.cpp +++ b/test/optional_test_wuninitialized.cpp @@ -123,6 +123,7 @@ void test_basics( ) optional oa ( a ) ; + optional ob ( a ); check_initialized(oa); oa = a ; @@ -132,7 +133,7 @@ void test_basics( ) optional const oa2 ( oa ) ; check_initialized_const(oa2); - oa = oa ; + oa = ob ; check_initialized(oa); oa = def ;