has_trivial_destructor and dtor optimization done.

[SVN r77235]
This commit is contained in:
Christopher Hite
2012-03-05 17:13:05 +00:00
parent cb9e852350
commit 7ac0cbe617
3 changed files with 56 additions and 4 deletions

View File

@ -26,6 +26,7 @@
#include <boost/type_traits/type_with_alignment.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/is_reference.hpp>
#include <boost/type_traits/has_trivial_destructor.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/not.hpp>
@ -168,6 +169,9 @@ struct types_when_is_ref
typedef raw_type& argument_type ;
} ;
template<typename T>
struct optional_dtor_optimized : has_trivial_destructor<T> {};
struct optional_tag {} ;
template<class T>
@ -199,6 +203,7 @@ class optional_base : public optional_tag
public:
typedef BOOST_DEDUCED_TYPENAME mpl::if_<is_reference_predicate,types_when_ref,types_when_not_ref>::type types ;
typedef optional_dtor_optimized<T> 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<T> (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<typename Optional,bool dtor_optimized> 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<typename Optional,bool dtor_optimized>
struct optional_dtor_mixin{
~optional_dtor_mixin(){ static_cast<Optional*>(this)->destructor_impl() ; }
};
template<typename Optional>
struct optional_dtor_mixin<Optional, true > { };
} // namespace optional_detail
template<class T>
class optional : public optional_detail::optional_base<T>
class optional :
public optional_detail::optional_base<T>,
public optional_detail::optional_dtor_mixin<optional<T>, optional_detail::optional_base<T>::dtor_optimized::value >
{
typedef optional_detail::optional_base<T> base ;
@ -566,7 +587,7 @@ class optional : public optional_detail::optional_base<T>
optional ( optional const& rhs ) : base( static_cast<base const&>(rhs) ) {}
// No-throw (assuming T::~T() doesn't)
~optional() {}
//~optional() {}
#if !defined(BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT) && !defined(BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION)
// Assigns from an expression. See corresponding constructor.

View File

@ -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 ]
;
}

View File

@ -0,0 +1,30 @@
#include "boost/optional.hpp"
#include "boost/static_assert.hpp"
#include "boost/type_traits.hpp"
using namespace boost;
typedef optional<char> oc;
typedef optional<int> oi;
typedef optional<std::string> os;
BOOST_STATIC_ASSERT( sizeof(oc) <= 2*sizeof(char) );
BOOST_STATIC_ASSERT( sizeof(oi) <= 2*sizeof(int) );
BOOST_STATIC_ASSERT( !has_trivial_default_constructor<oi>::value ); //never true for optional
BOOST_STATIC_ASSERT( !has_trivial_default_constructor<os>::value );
BOOST_STATIC_ASSERT( has_trivial_destructor<oi>::value ); //should be true where has_trivial_destructor<T>
BOOST_STATIC_ASSERT( !has_trivial_destructor<os>::value );
/*
has_trivial_assign
has_trivial_constructor
has_trivial_copy
has_trivial_copy_constructor
has_trivial_default_constructor
has_trivial_destructor
*/