From 7ac0cbe617452b8fde78e45b3983431cb1cddeb3 Mon Sep 17 00:00:00 2001 From: Christopher Hite Date: Mon, 5 Mar 2012 17:13:05 +0000 Subject: [PATCH] has_trivial_destructor and dtor optimization done. [SVN r77235] --- include/boost/optional/optional.hpp | 29 +++++++++++++++++++--- test/Jamfile.v2 | 1 + test/optional_test_trivial_assertions.cpp | 30 +++++++++++++++++++++++ 3 files changed, 56 insertions(+), 4 deletions(-) create mode 100644 test/optional_test_trivial_assertions.cpp diff --git a/include/boost/optional/optional.hpp b/include/boost/optional/optional.hpp index 750f397..4d58093 100644 --- a/include/boost/optional/optional.hpp +++ b/include/boost/optional/optional.hpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -168,6 +169,9 @@ struct types_when_is_ref typedef raw_type& argument_type ; } ; +template +struct optional_dtor_optimized : has_trivial_destructor {}; + struct optional_tag {} ; template @@ -199,6 +203,7 @@ class optional_base : public optional_tag public: typedef BOOST_DEDUCED_TYPENAME mpl::if_::type types ; + typedef optional_dtor_optimized dtor_optimized; protected: typedef bool (this_type::*unspecified_bool_type)() const; @@ -265,7 +270,7 @@ class optional_base : public optional_tag // No-throw (assuming T::~T() doesn't) - ~optional_base() { destroy() ; } + //~optional_base() { destroy() ; } // Assigns from another optional (deep-copies the rhs value) void assign ( optional_base const& rhs ) @@ -440,6 +445,12 @@ class optional_base : public optional_tag m_initialized = false ; } } + void destructor_impl() // doesn't reset m_initialized + { + if(m_initialized) + destroy_impl(is_reference_predicate()) ; + } + template friend class optional_dtor_mixin; unspecified_bool_type safe_bool() const { return m_initialized ? &this_type::is_initialized : 0 ; } @@ -495,10 +506,20 @@ class optional_base : public optional_tag storage_type m_storage ; } ; +template +struct optional_dtor_mixin{ + ~optional_dtor_mixin(){ static_cast(this)->destructor_impl() ; } +}; + +template +struct optional_dtor_mixin { }; + } // namespace optional_detail template -class optional : public optional_detail::optional_base +class optional : + public optional_detail::optional_base, + public optional_detail::optional_dtor_mixin, optional_detail::optional_base::dtor_optimized::value > { typedef optional_detail::optional_base base ; @@ -565,8 +586,8 @@ class optional : public optional_detail::optional_base // Can throw if T::T(T const&) does optional ( optional const& rhs ) : base( static_cast(rhs) ) {} - // No-throw (assuming T::~T() doesn't) - ~optional() {} + // No-throw (assuming T::~T() doesn't) + //~optional() {} #if !defined(BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT) && !defined(BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION) // Assigns from an expression. See corresponding constructor. diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 16d4f3c..94b2edf 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -29,5 +29,6 @@ import testing ; [ compile-fail optional_test_ref_fail4.cpp ] [ compile-fail optional_test_inplace_fail.cpp ] [ compile-fail optional_test_inplace_fail2.cpp ] + [ compile optional_test_trivial_assertions.cpp ] ; } diff --git a/test/optional_test_trivial_assertions.cpp b/test/optional_test_trivial_assertions.cpp new file mode 100644 index 0000000..4a565c0 --- /dev/null +++ b/test/optional_test_trivial_assertions.cpp @@ -0,0 +1,30 @@ +#include "boost/optional.hpp" +#include "boost/static_assert.hpp" +#include "boost/type_traits.hpp" + +using namespace boost; + +typedef optional oc; +typedef optional oi; +typedef optional os; + +BOOST_STATIC_ASSERT( sizeof(oc) <= 2*sizeof(char) ); +BOOST_STATIC_ASSERT( sizeof(oi) <= 2*sizeof(int) ); + +BOOST_STATIC_ASSERT( !has_trivial_default_constructor::value ); //never true for optional +BOOST_STATIC_ASSERT( !has_trivial_default_constructor::value ); + +BOOST_STATIC_ASSERT( has_trivial_destructor::value ); //should be true where has_trivial_destructor +BOOST_STATIC_ASSERT( !has_trivial_destructor::value ); + + +/* +has_trivial_assign +has_trivial_constructor +has_trivial_copy +has_trivial_copy_constructor +has_trivial_default_constructor +has_trivial_destructor + */ + +