On Sep 15, 2010, at 10:28 AM, Hite, Christopher wrote:

I noticed poor performance coping a  structure with a bunch of optionals.  The reason is the cost of checking if the optionals are set.  CPU's hate branching it breaks their pipelining.

        if(that->a)
                this->a=*that->a;
At the end of the day I just wrote a copy construct which does a memcpy(), since the data types were just POD.  It makes me a bit nervous since my code might break with a different impl of opitonal.

Then I thought hey wouldn't it be cool if defined a metafunction that specified memcpy/memmove are allowed?  It looks like has_trivial_copy<> fits the bill.


// Suggested code:
namespace boost{

template<typename T>
struct has_trivial_copy< boost::optional<T> > :
        has_trivial_copy<T> {};

}//namespace boost


typedef boost::optional<int> OptionalInt;
BOOST_STATIC_ASSERT(( has_trivial_copy<OptionalInt>::value )); //fixed thanks to code above

struct SomeOptionals{ OptionalInt a,b;};
BOOST_STATIC_ASSERT(( has_trivial_copy<SomeOptionals>::value )); //fails

The second test fails. 

As well it should.  It would be a lie, because the copy c'tor is nontrivial in all cases, even when a trivial copy c'tor would work.

It can't imagine how to make it work without some compiler magic.  I wonder if a compiler could use metafunctions to know which optimizations were legal.

It could, when those metafunctions are in std::, and all the type traits will be in std:: for C++0x.

Similar meta function specializations could be written for boost::variant and boost::fusion::map.  I could imagine contains like std::vector using this to do memmove() for example.

It looks to me as though the right place to fix this is in boost::optional<T>: it should be specialized so that when has a trivial copy c'tor, so does boost::optional<T>.  I suggest you open a Trac ticket at http://svn.boost.org/trac/boost

--
Dave Abrahams
BoostPro Computing