Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r82811 - sandbox/varray/boost/container/detail
From: adam.wulkiewicz_at_[hidden]
Date: 2013-02-10 18:05:59


Author: awulkiew
Date: 2013-02-10 18:05:58 EST (Sun, 10 Feb 2013)
New Revision: 82811
URL: http://svn.boost.org/trac/boost/changeset/82811

Log:
initialization of trivially constructable values in emplace() and emplace_back() may be disabled in traits.
partial specialization enabled conditional compilation removed.
Text files modified:
   sandbox/varray/boost/container/detail/varray.hpp | 46 +++++++----
   sandbox/varray/boost/container/detail/varray_util.hpp | 165 ++++++++-------------------------------
   2 files changed, 63 insertions(+), 148 deletions(-)

Modified: sandbox/varray/boost/container/detail/varray.hpp
==============================================================================
--- sandbox/varray/boost/container/detail/varray.hpp (original)
+++ sandbox/varray/boost/container/detail/varray.hpp 2013-02-10 18:05:58 EST (Sun, 10 Feb 2013)
@@ -704,10 +704,12 @@
     //! Constant O(1).
     void push_back(value_type const& value)
     {
+ typedef typename vt::disable_trivial_init dti;
+
         errh::check_capacity(*this, m_size + 1); // may throw
         
         namespace sv = varray_detail;
- sv::construct(this->end(), value); // may throw
+ sv::construct(dti(), this->end(), value); // may throw
         ++m_size; // update end
     }
 
@@ -727,10 +729,12 @@
     //! Constant O(1).
     void push_back(BOOST_RV_REF(value_type) value)
     {
+ typedef typename vt::disable_trivial_init dti;
+
         errh::check_capacity(*this, m_size + 1); // may throw
 
         namespace sv = varray_detail;
- sv::construct(this->end(), value); // may throw
+ sv::construct(dti(), this->end(), value); // may throw
         ++m_size; // update end
     }
 
@@ -1017,12 +1021,14 @@
     //! @par Complexity
     //! Constant O(1).
     template<class ...Args>
- void emplace_back(Args &&...args)
+ void emplace_back(BOOST_FWD_REF(Args) ...args)
     {
+ typedef typename vt::disable_trivial_init dti;
+
         errh::check_capacity(*this, m_size + 1); // may throw
 
         namespace sv = varray_detail;
- sv::construct(this->end(), ::boost::forward<Args>(args)...); // may throw
+ sv::construct(dti(), this->end(), ::boost::forward<Args>(args)...); // may throw
         ++m_size; // update end
     }
 
@@ -1045,8 +1051,10 @@
     //! @par Complexity
     //! Constant or linear.
     template<class ...Args>
- iterator emplace(iterator position, Args &&...args)
+ iterator emplace(iterator position, BOOST_FWD_REF(Args) ...args)
     {
+ typedef typename vt::disable_trivial_init dti;
+
         namespace sv = varray_detail;
 
         errh::check_iterator_end_eq(*this, position);
@@ -1054,7 +1062,7 @@
 
         if ( position == this->end() )
         {
- sv::construct(position, ::boost::forward<Args>(args)...); // may throw
+ sv::construct(dti(), position, ::boost::forward<Args>(args)...); // may throw
             ++m_size; // update end
         }
         else
@@ -1063,13 +1071,13 @@
 
             // TODO - should move be used only if it's nonthrowing?
             value_type & r = *(this->end() - 1);
- sv::construct(this->end(), boost::move(r)); // may throw
+ sv::construct(dti(), this->end(), boost::move(r)); // may throw
             ++m_size; // update end
             sv::move_backward(position, this->end() - 2, this->end() - 1); // may throw
 
             aligned_storage<sizeof(value_type), alignment_of<value_type>::value> temp_storage;
             value_type * val_p = static_cast<value_type *>(temp_storage.address());
- sv::construct(val_p, ::boost::forward<Args>(args)...); // may throw
+ sv::construct(dti(), val_p, ::boost::forward<Args>(args)...); // may throw
             sv::scoped_destructor<value_type> d(val_p);
             sv::assign(position, ::boost::move(*val_p)); // may throw
         }
@@ -1083,10 +1091,12 @@
     BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
     void emplace_back(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
     { \
+ typedef typename vt::disable_trivial_init dti; \
+ \
         errh::check_capacity(*this, m_size + 1); /*may throw*/\
                                                                                                  \
         namespace sv = varray_detail; \
- sv::construct(this->end() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); /*may throw*/\
+ sv::construct(dti(), this->end() BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); /*may throw*/\
         ++m_size; /*update end*/ \
     } \
     //
@@ -1097,14 +1107,15 @@
     BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
     iterator emplace(iterator position BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
     { \
- namespace sv = varray_detail; \
+ typedef typename vt::disable_trivial_init dti; \
+ namespace sv = varray_detail; \
                                                                                                     \
         errh::check_iterator_end_eq(*this, position); \
         errh::check_capacity(*this, m_size + 1); /*may throw*/\
                                                                                                     \
         if ( position == this->end() ) \
         { \
- sv::construct(position BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); /*may throw*/\
+ sv::construct(dti(), position BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); /*may throw*/\
             ++m_size; /*update end*/ \
         } \
         else \
@@ -1113,13 +1124,13 @@
             /* TODO - should move be used only if it's nonthrowing? */ \
                                                                                                     \
             value_type & r = *(this->end() - 1); \
- sv::construct(this->end(), boost::move(r)); /*may throw*/\
+ sv::construct(dti(), this->end(), boost::move(r)); /*may throw*/\
             ++m_size; /*update end*/ \
             sv::move_backward(position, this->end() - 2, this->end() - 1); /*may throw*/\
                                                                                                     \
             aligned_storage<sizeof(value_type), alignment_of<value_type>::value> temp_storage; \
             value_type * val_p = static_cast<value_type *>(temp_storage.address()); \
- sv::construct(val_p BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); /*may throw*/\
+ sv::construct(dti(), val_p BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _) ); /*may throw*/\
             sv::scoped_destructor<value_type> d(val_p); \
             sv::assign(position, ::boost::move(*val_p)); /*may throw*/\
         } \
@@ -1677,6 +1688,7 @@
     template <typename V>
     iterator priv_insert(iterator position, V & value)
     {
+ typedef typename vt::disable_trivial_init dti;
         namespace sv = varray_detail;
 
         errh::check_iterator_end_eq(*this, position);
@@ -1684,7 +1696,7 @@
 
         if ( position == this->end() )
         {
- sv::construct(position, value); // may throw
+ sv::construct(dti(), position, value); // may throw
             ++m_size; // update end
         }
         else
@@ -1693,7 +1705,7 @@
 
             // TODO - should move be used only if it's nonthrowing?
             value_type & r = *(this->end() - 1);
- sv::construct(this->end(), boost::move(r)); // may throw
+ sv::construct(dti(), this->end(), boost::move(r)); // may throw
             ++m_size; // update end
             sv::move_backward(position, this->end() - 2, this->end() - 1); // may throw
             sv::assign(position, value); // may throw
@@ -1870,7 +1882,7 @@
     aligned_storage_type m_storage;
 };
 
-#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
+#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
 
 template<typename Value, typename Strategy>
 class varray<Value, 0, Strategy>
@@ -2130,7 +2142,7 @@
     }
 };
 
-#endif // !BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION && !BOOST_CONTAINER_DOXYGEN_INVOKED
+#endif // !BOOST_CONTAINER_DOXYGEN_INVOKED
 
 //! @brief Checks if contents of two varrays are equal.
 //!

Modified: sandbox/varray/boost/container/detail/varray_util.hpp
==============================================================================
--- sandbox/varray/boost/container/detail/varray_util.hpp (original)
+++ sandbox/varray/boost/container/detail/varray_util.hpp 2013-02-10 18:05:58 EST (Sun, 10 Feb 2013)
@@ -42,8 +42,6 @@
 
 // TODO - move vectors iterators optimization to the other, optional file instead of checking defines?
 
-#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
-
 #if defined(BOOST_CONTAINER_VARRAY_ENABLE_VECTORS_OPTIMIZATION) && !defined(BOOST_NO_EXCEPTIONS)
 #include <vector>
 #include <boost/container/vector.hpp>
@@ -110,18 +108,8 @@
 
 }}} // namespace boost::container::varray_detail
 
-#endif // !BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
-
 namespace boost { namespace container { namespace varray_detail {
 
-// TODO
-// Does BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION checks have any sense?
-// Boost.MPL and Boost.Container might not be used but
-// Boost.Iterator also uses partial specialization
-// and in fact iterator_traits won't work if there is no partial specialization
-
-#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
-
 template <typename I, typename O>
 struct are_corresponding :
     ::boost::mpl::and_<
@@ -507,19 +495,37 @@
 void uninitialized_fill(I first, I last, DisableTrivialInit const& disable_trivial_init)
 {
     typedef typename boost::iterator_value<I>::type value_type;
- uninitialized_fill_dispatch(first, last, has_trivial_constructor<value_type>(), disable_trivial_init); // may throw
+ uninitialized_fill_dispatch(first, last, boost::has_trivial_constructor<value_type>(), disable_trivial_init); // may throw
 }
 
 // construct(I)
 
 template <typename I>
 inline
-void construct(I pos)
+void construct_dispatch(boost::mpl::bool_<true> const& /*dont_init*/, I pos)
+{}
+
+template <typename I>
+inline
+void construct_dispatch(boost::mpl::bool_<false> const& /*dont_init*/, I pos)
 {
     typedef typename ::boost::iterator_value<I>::type value_type;
     new (static_cast<void*>(::boost::addressof(*pos))) value_type(); // may throw
 }
 
+template <typename DisableTrivialInit, typename I>
+inline
+void construct(DisableTrivialInit const&, I pos)
+{
+ typedef typename ::boost::iterator_value<I>::type value_type;
+ typedef typename ::boost::mpl::and_<
+ boost::has_trivial_constructor<value_type>,
+ DisableTrivialInit
+ >::type dont_init;
+
+ construct_dispatch(dont_init(), pos); // may throw
+}
+
 // construct(I, V)
 
 template <typename I, typename V>
@@ -539,9 +545,10 @@
     new (static_cast<void*>(boost::addressof(*pos))) V(p); // may throw
 }
 
-template <typename I, typename P>
+template <typename DisableTrivialInit, typename I, typename P>
 inline
-void construct(I pos, P const& p)
+void construct(DisableTrivialInit const&,
+ I pos, P const& p)
 {
     typedef typename
     ::boost::mpl::and_<
@@ -555,9 +562,9 @@
 
 // Needed by push_back(V &&)
 
-template <typename I, typename P>
+template <typename DisableTrivialInit, typename I, typename P>
 inline
-void construct(I pos, BOOST_RV_REF(P) p)
+void construct(DisableTrivialInit const&, I pos, BOOST_RV_REF(P) p)
 {
     typedef typename
     ::boost::mpl::and_<
@@ -575,9 +582,11 @@
 #if !defined(BOOST_CONTAINER_VARRAY_DISABLE_EMPLACE)
 #if !defined(BOOST_NO_VARIADIC_TEMPLATES)
 
-template <typename I, class ...Args>
+template <typename DisableTrivialInit, typename I, class ...Args>
 inline
-void construct(I pos, BOOST_FWD_REF(Args) ...args)
+void construct(DisableTrivialInit const&,
+ I pos,
+ BOOST_FWD_REF(Args) ...args)
 {
     typedef typename boost::iterator_value<I>::type V;
     new (static_cast<void*>(boost::addressof(*pos))) V(::boost::forward<Args>(args)...); // may throw
@@ -590,9 +599,10 @@
 // which means that version with one parameter may take V const& v
 
 #define BOOST_PP_LOCAL_MACRO(n) \
-template <typename I, typename P BOOST_PP_ENUM_TRAILING_PARAMS(n, typename P) > \
+template <typename DisableTrivialInit, typename I, typename P BOOST_PP_ENUM_TRAILING_PARAMS(n, typename P) > \
 inline \
-void construct(I pos, \
+void construct(DisableTrivialInit const&, \
+ I pos, \
                BOOST_CONTAINER_PP_PARAM(P, p) \
                BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
 { \
@@ -647,114 +657,6 @@
     *pos = v; // may throw
 }
 
-#else // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
-
-template <typename I, typename O>
-inline O copy(I first, I last, O dst)
-{
- return std::copy(first, last, dst); // may throw
-}
-
-template <typename I, typename F>
-inline F uninitialized_copy(I first, I last, F dst)
-{
- return std::uninitialized_copy(first, last, dst); // may throw
-}
-
-template <typename I, typename O>
-inline O move(I first, I last, O dst)
-{
- return std::copy(first, last, dst); // may throw
-}
-
-template <typename BDI, typename BDO>
-inline BDO move_backward(BDI first, BDI last, BDO dst)
-{
- return std::copy_backward(first, last, dst); // may throw
-}
-
-template <typename I, typename O>
-inline O uninitialized_move(I first, I last, O dst)
-{
- //return boost::uninitialized_move(first, last, dst); // may throw
-
- O o = dst;
-
- BOOST_TRY
- {
- typedef typename std::iterator_traits<O>::value_type value_type;
- for (; first != last; ++first, ++o )
- new (boost::addressof(*o)) value_type(boost::move(*first));
- }
- BOOST_CATCH(...)
- {
- destroy(dst, o);
- BOOST_RETHROW;
- }
- BOOST_CATCH_END
-
- return dst;
-}
-
-template <typename I, typename O>
-inline O uninitialized_move_if_noexcept(I first, I last, O dst)
-{
- return uninitialized_copy(first, last, dst); // may throw
-}
-
-template <typename I, typename O>
-inline O move_if_noexcept(I first, I last, O dst)
-{
- return copy(first, last, dst); // may throw
-}
-
-template <typename I>
-inline void destroy(I first, I last)
-{
- typedef typename boost::iterator_value<I>::type value_type;
- for ( ; first != last ; ++first )
- first->~value_type();
-}
-
-template <typename I>
-inline void destroy(I pos)
-{
- typedef typename boost::iterator_value<I>::type value_type;
- pos->~value_type();
-}
-
-template <typename I>
-inline void uninitialized_fill(I first, I last)
-{
- typedef typename boost::iterator_value<I>::type value_type;
- I it = first;
-
- BOOST_TRY
- {
- for ( ; it != last ; ++it )
- new (boost::addressof(*it)) value_type(); // may throw
- }
- BOOST_CATCH(...)
- {
- destroy(first, it);
- BOOST_RETHROW;
- }
- BOOST_CATCH_END
-}
-
-template <typename I, typename V>
-inline void construct(I pos, V const& v)
-{
- new (static_cast<void*>(boost::addressof(*pos))) V(v); // may throw
-}
-
-template <typename I, typename V>
-inline void assign(I pos, V const& v)
-{
- *pos = v; // may throw
-}
-
-#endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
 
 // uninitialized_copy_s
 
@@ -771,7 +673,8 @@
             if ( max_count <= count )
                 return (std::numeric_limits<std::size_t>::max)();
 
- construct(it, *first); // may throw
+ // dummy 0 as DisableTrivialInit
+ construct(0, it, *first); // may throw
         }
     }
     BOOST_CATCH(...)


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