Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r67798 - trunk/boost/variant
From: steven_at_[hidden]
Date: 2011-01-08 17:44:11


Author: steven_watanabe
Date: 2011-01-08 17:44:06 EST (Sat, 08 Jan 2011)
New Revision: 67798
URL: http://svn.boost.org/trac/boost/changeset/67798

Log:
Avoid a quadratic number of template instantations when using the general case implementation of assignment (with backup storage). This significantly improves compile times for variants with a large number of variant types. See the thread starting at http://lists.boost.org/boost-users/2011/01/65416.php.
Text files modified:
   trunk/boost/variant/variant.hpp | 23 ++++++++++++++++-------
   1 files changed, 16 insertions(+), 7 deletions(-)

Modified: trunk/boost/variant/variant.hpp
==============================================================================
--- trunk/boost/variant/variant.hpp (original)
+++ trunk/boost/variant/variant.hpp 2011-01-08 17:44:06 EST (Sat, 08 Jan 2011)
@@ -567,7 +567,7 @@
 // NOTE: This needs to be a friend of variant, as it needs access to
 // indicate_which, indicate_backup_which, etc.
 //
-template <typename Variant, typename RhsT>
+template <typename Variant>
 class backup_assigner
     : public static_visitor<>
 {
@@ -575,19 +575,28 @@
 
     Variant& lhs_;
     int rhs_which_;
- const RhsT& rhs_content_;
+ const void* rhs_content_;
+ void (*copy_rhs_content_)(void*, const void*);
 
 public: // structors
 
+ template<class RhsT>
     backup_assigner(Variant& lhs, int rhs_which, const RhsT& rhs_content)
         : lhs_(lhs)
         , rhs_which_(rhs_which)
- , rhs_content_(rhs_content)
+ , rhs_content_(&rhs_content)
+ , copy_rhs_content_(&construct_impl<RhsT>)
     {
     }
 
 private: // helpers, for visitor interface (below)
 
+ template<class RhsT>
+ static void construct_impl(void* addr, const void* obj)
+ {
+ new(addr) RhsT(*static_cast<const RhsT*>(obj));
+ }
+
     template <typename LhsT>
     void backup_assign_impl(
           LhsT& lhs_content
@@ -605,7 +614,7 @@
         try
         {
             // ...and attempt to copy rhs content into lhs storage:
- new(lhs_.storage_.address()) RhsT(rhs_content_);
+ copy_rhs_content_(lhs_.storage_.address(), rhs_content_);
         }
         catch (...)
         {
@@ -638,7 +647,7 @@
         try
         {
             // ...and attempt to copy rhs content into lhs storage:
- new(lhs_.storage_.address()) RhsT(rhs_content_);
+ copy_rhs_content_(lhs_.storage_.address(), rhs_content_);
         }
         catch (...)
         {
@@ -1448,7 +1457,7 @@
 private: // helpers, for modifiers (below)
 
 # if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
- template <typename Variant, typename RhsT>
+ template <typename Variant>
     friend class detail::variant::backup_assigner;
 # endif
 
@@ -1561,7 +1570,7 @@
             , mpl::false_// has_fallback_type
             )
         {
- detail::variant::backup_assigner<wknd_self_t, RhsT>
+ detail::variant::backup_assigner<wknd_self_t>
                 visitor(lhs_, rhs_which_, rhs_content);
             lhs_.internal_apply_visitor(visitor);
         }


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk