diff --git a/include/libimp/detect_plat.h b/include/libimp/detect_plat.h index 1206d06..a38dac2 100644 --- a/include/libimp/detect_plat.h +++ b/include/libimp/detect_plat.h @@ -208,11 +208,11 @@ /// https://stackoverflow.com/questions/6487013/programmatically-determine-whether-exceptions-are-enabled #if defined(__cpp_exceptions) && __cpp_exceptions || \ defined(__EXCEPTIONS) || defined(_CPPUNWIND) -# define LIBIMP_TRY try -# define LIBIMP_CATCH(...) catch (__VA_ARGS__) -# define LIBIMP_THROW($exception, $ret) throw $exception +# define LIBIMP_TRY try +# define LIBIMP_CATCH(...) catch (__VA_ARGS__) +# define LIBIMP_THROW($exception, ...) throw $exception #else -# define LIBIMP_TRY if (true) -# define LIBIMP_CATCH(...) else if (false) -# define LIBIMP_THROW($exception, $ret) return $ret -#endif \ No newline at end of file +# define LIBIMP_TRY if (true) +# define LIBIMP_CATCH(...) else if (false) +# define LIBIMP_THROW($exception, ...) return __VA_ARGS__ +#endif diff --git a/include/libimp/uninitialized.h b/include/libimp/uninitialized.h index 7837bf9..b352500 100644 --- a/include/libimp/uninitialized.h +++ b/include/libimp/uninitialized.h @@ -100,7 +100,7 @@ ForwardIt destroy_n(ForwardIt first, Size n) noexcept { /** * \brief Constructs objects by default-initialization - * in an uninitialized area of memory, defined by a start and a count. + * in an uninitialized area of memory, defined by a start and a count. * \see https://en.cppreference.com/w/cpp/memory/uninitialized_default_construct_n */ template @@ -121,4 +121,28 @@ ForwardIt uninitialized_default_construct_n(ForwardIt first, Size n) { #endif } +/** +* \brief Moves a number of objects to an uninitialized area of memory. +* \see https://en.cppreference.com/w/cpp/memory/uninitialized_move_n +*/ +template +auto uninitialized_move_n(InputIt first, Size count, NoThrowForwardIt d_first) + -> std::pair { +#if defined(LIBIMP_CPP_17) + return std::uninitialized_move_n(first, count, d_first); +#else + using Value = typename std::iterator_traits::value_type; + NoThrowForwardIt current = d_first; + LIBIMP_TRY { + for (; count > 0; ++first, (void) ++current, --count) { + ::new (static_cast(std::addressof(*current))) Value(std::move(*first)); + } + } LIBIMP_CATCH(...) { + destroy(d_first, current); + LIBIMP_THROW(, {first, d_first}); + } + return {first, current}; +#endif +} + LIBIMP_NAMESPACE_END_ diff --git a/include/libpmr/small_storage.h b/include/libpmr/small_storage.h index 6e383f3..faff459 100644 --- a/include/libpmr/small_storage.h +++ b/include/libpmr/small_storage.h @@ -219,7 +219,7 @@ struct holder_type : holder_type_base { std::type_info const &type() const noexcept override { return typeid(Value); } void move(void *s, void *d, std::size_t n) const noexcept override { - std::uninitialized_move_n(static_cast(s), n, static_cast(d)); + ::LIBIMP::uninitialized_move_n(static_cast(s), n, static_cast(d)); } void copy(void const *s, void *d, std::size_t n) const noexcept(false) override { std::uninitialized_copy_n(static_cast(s), n, static_cast(d));