21 #ifndef RANGES_V3_UTILITY_MEMORY_HPP
22 #define RANGES_V3_UTILITY_MEMORY_HPP
26 #include <type_traits>
31 #include <range/v3/detail/config.hpp>
34 #include <range/v3/utility/polymorphic_cast.hpp>
36 #include <range/v3/detail/prologue.hpp>
44 std::pair<T *, std::ptrdiff_t> get_temporary_buffer_impl(
std::size_t n) noexcept
46 if(n > PTRDIFF_MAX /
sizeof(T))
47 n = PTRDIFF_MAX /
sizeof(T);
50 for(; ptr ==
nullptr && n > 0; n /= 2)
52 #if RANGES_CXX_ALIGNED_NEW < RANGES_CXX_ALIGNED_NEW_17
53 static_assert(
alignof(T) <=
alignof(std::max_align_t),
54 "Sorry: over-aligned types are supported only with C++17.");
56 if(RANGES_CONSTEXPR_IF(
alignof(T) > __STDCPP_DEFAULT_NEW_ALIGNMENT__))
58 sizeof(T) * n, std::align_val_t{
alignof(T)}, std::nothrow);
61 ptr = ::operator
new(
sizeof(T) * n, std::nothrow);
64 return {
static_cast<T *
>(ptr),
static_cast<std::ptrdiff_t
>(n)};
67 template<
typename T,
typename D>
68 std::pair<T *, std::ptrdiff_t> get_temporary_buffer(D
count) noexcept
70 RANGES_EXPECT(
count >= 0);
71 return detail::get_temporary_buffer_impl<T>(
static_cast<std::size_t>(
count));
74 struct return_temporary_buffer
77 void operator()(T * p)
const
79 #if RANGES_CXX_ALIGNED_NEW < RANGES_CXX_ALIGNED_NEW_17
80 static_assert(
alignof(T) <=
alignof(std::max_align_t),
81 "Sorry: over-aligned types are supported only with C++17.");
83 if(RANGES_CONSTEXPR_IF(
alignof(T) > __STDCPP_DEFAULT_NEW_ALIGNMENT__))
84 ::operator
delete(p, std::align_val_t{
alignof(T)});
91 template(
typename T,
typename... Args)(
92 requires (!std::is_array<T>::value))
93 std::unique_ptr<T> make_unique(Args &&... args)
95 return std::unique_ptr<T>{
new T(
static_cast<Args &&
>(args)...)};
102 template<
typename O,
typename Val>
106 CPP_assert(output_iterator<O, Val>);
107 CPP_assert(std::is_lvalue_reference<iter_reference_t<O>>());
111 using difference_type = iter_difference_t<O>;
114 : out_(std::move(out))
121 auto operator=(Val
const & val)
123 requires copy_constructible<Val>)
125 ::new((
void *)std::addressof(*out_)) Val(val);
129 auto operator=(Val && val)
131 requires move_constructible<Val>)
133 ::new((
void *)std::addressof(*out_)) Val(std::move(val));
144 requires (!forward_iterator<O>))
151 requires forward_iterator<O>)
167 CPP_assert(input_or_output_iterator<I>);
168 mutable I * i_ =
nullptr;
171 using difference_type = iter_difference_t<I>;
185 : i_(std::addressof(i))
188 auto CPP_auto_fun(
operator*)()(
const)
209 template(
typename I)(
210 requires input_or_output_iterator<I>)
221 template<
typename Val>
237 for(; begin_ != rsi_.base(); ++begin_)
242 return ranges::iter_ref(rsi_);
246 template<
typename Val>
254 #include <range/v3/detail/epilogue.hpp>
std::integral_constant< std::size_t, N > size_t
An integral constant wrapper for std::size_t.
Definition: meta.hpp:163
front< Pair > first
Retrieve the first element of the pair Pair.
Definition: meta.hpp:2251
_t< detail::count_< L, T > > count
Count the number of times a type T appears in the list L.
Definition: meta.hpp:2725
Definition: associated_types.hpp:236
Definition: memory.hpp:165
Definition: memory.hpp:223
Definition: memory.hpp:104