Add alternative sp_array_construct for trivially destructible case

This commit is contained in:
Glen Fernandes
2017-04-22 22:39:57 -04:00
parent 7ef8fa4a19
commit e99e722fa5

View File

@@ -9,9 +9,10 @@ Distributed under the Boost Software License, Version 1.0.
#define BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP #define BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP
#include <boost/smart_ptr/shared_ptr.hpp> #include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/type_traits/has_trivial_constructor.hpp>
#include <boost/type_traits/has_trivial_destructor.hpp>
#include <boost/type_traits/alignment_of.hpp> #include <boost/type_traits/alignment_of.hpp>
#include <boost/type_traits/has_trivial_constructor.hpp>
#include <boost/type_traits/has_trivial_copy.hpp>
#include <boost/type_traits/has_trivial_destructor.hpp>
#include <boost/type_traits/type_with_alignment.hpp> #include <boost/type_traits/type_with_alignment.hpp>
namespace boost { namespace boost {
@@ -173,7 +174,7 @@ inline void
sp_array_destroy(A& allocator, T* storage, std::size_t size) sp_array_destroy(A& allocator, T* storage, std::size_t size)
{ {
while (size > 0) { while (size > 0) {
std::allocator_traits<A>::destroy(allocator, &storage[--size]); std::allocator_traits<A>::destroy(allocator, storage + --size);
} }
} }
#endif #endif
@@ -202,15 +203,27 @@ sp_array_construct(T* storage, std::size_t size)
::new(static_cast<void*>(storage + i)) T(); ::new(static_cast<void*>(storage + i)) T();
} }
} catch (...) { } catch (...) {
while (i > 0) { sp_array_destroy(storage, i);
storage[--i].~T();
}
throw; throw;
} }
} }
template<class T> template<class T>
inline void inline
typename sp_enable<boost::has_trivial_copy_constructor<T>::value ||
boost::has_trivial_destructor<T>::value>::type
sp_array_construct(T* storage, std::size_t size, const T* list,
std::size_t count)
{
for (std::size_t i = 0; i < size; ++i) {
::new(static_cast<void*>(storage + i)) T(list[i % count]);
}
}
template<class T>
inline
typename sp_enable<!boost::has_trivial_copy_constructor<T>::value &&
!boost::has_trivial_destructor<T>::value>::type
sp_array_construct(T* storage, std::size_t size, const T* list, sp_array_construct(T* storage, std::size_t size, const T* list,
std::size_t count) std::size_t count)
{ {
@@ -220,9 +233,7 @@ sp_array_construct(T* storage, std::size_t size, const T* list,
::new(static_cast<void*>(storage + i)) T(list[i % count]); ::new(static_cast<void*>(storage + i)) T(list[i % count]);
} }
} catch (...) { } catch (...) {
while (i > 0) { sp_array_destroy(storage, i);
storage[--i].~T();
}
throw; throw;
} }
} }
@@ -332,9 +343,7 @@ sp_array_default(T* storage, std::size_t size)
::new(static_cast<void*>(storage + i)) T; ::new(static_cast<void*>(storage + i)) T;
} }
} catch (...) { } catch (...) {
while (i > 0) { sp_array_destroy(storage, i);
storage[--i].~T();
}
throw; throw;
} }
} }