Skip to main content

std::ranges::uninitialized_fill_n() algorithm

// (1)
I uninitialized_fill_n( I first, std::iter_difference_t<I> n, const T& x );

The type of arguments are generic and have following constraints:

Additionally, each overload has the following constraints:

  • (1) std::constructible_from<std::iter_value_t<I>, const T& >

Constructs n copies of the given value x in an uninitialized memory area, designated by the range [first; first + n), as if by:

for (; n--; ++first) {
::new (static_cast<void*>(std::addressof(*first)))
std::remove_reference_t<std::iter_reference_t<I>>(x);
}
caution

If an exception is thrown during the initialization, the objects already constructed are destroyed in an unspecified order.

The function-like entities described on this page are niebloids.

Parameters

first

The beginning of the range of the elements to initialize.

n

Number of elements to construct.

x

The value to construct the elements with.

Return value

An iterator equal to first + n.

Complexity

Linear in n.

Exceptions

The exception thrown on construction of the elements in the destination range, if any.

Possible implementation

uninitialized_fill_n(1)
struct uninitialized_fill_n_fn
{
template<no-throw-forward-range I, class T>
requires std::constructible_from<std::iter_value_t<I>, const T&>
I operator()(I first, std::iter_difference_t<I> n, const T& x) const
{
I rollback{first};
try
{
for (; n-- > 0; ++first)
ranges::construct_at(std::addressof(*first), x);
return first;
}
catch (...) // rollback: destroy constructed elements
{
for (; rollback != first; ++rollback)
ranges::destroy_at(std::addressof(*rollback));
throw;
}
}
};

inline constexpr uninitialized_fill_n_fn uninitialized_fill_n{};

Examples

Main.cpp
#include <iostream>
#include <memory>
#include <string>

int main()
{
constexpr int n{3};
alignas(alignof(std::string)) char out[n * sizeof(std::string)];

try
{
auto first{reinterpret_cast<std::string*>(out)};
auto last = std::ranges::uninitialized_fill_n(first, n, "cppreference");

for (auto it{first}; it != last; ++it)
std::cout << *it << '\n';

std::ranges::destroy(first, last);
}
catch (...)
{
std::cout << "Exception!\n";
}
}
Output
cppreference
cppreference
cppreference
This article originates from this CppReference page. It was likely altered for improvements or editors' preference. Click "Edit this page" to see all changes made to this document.
Hover to see the original license.

std::ranges::uninitialized_fill_n() algorithm

// (1)
I uninitialized_fill_n( I first, std::iter_difference_t<I> n, const T& x );

The type of arguments are generic and have following constraints:

Additionally, each overload has the following constraints:

  • (1) std::constructible_from<std::iter_value_t<I>, const T& >

Constructs n copies of the given value x in an uninitialized memory area, designated by the range [first; first + n), as if by:

for (; n--; ++first) {
::new (static_cast<void*>(std::addressof(*first)))
std::remove_reference_t<std::iter_reference_t<I>>(x);
}
caution

If an exception is thrown during the initialization, the objects already constructed are destroyed in an unspecified order.

The function-like entities described on this page are niebloids.

Parameters

first

The beginning of the range of the elements to initialize.

n

Number of elements to construct.

x

The value to construct the elements with.

Return value

An iterator equal to first + n.

Complexity

Linear in n.

Exceptions

The exception thrown on construction of the elements in the destination range, if any.

Possible implementation

uninitialized_fill_n(1)
struct uninitialized_fill_n_fn
{
template<no-throw-forward-range I, class T>
requires std::constructible_from<std::iter_value_t<I>, const T&>
I operator()(I first, std::iter_difference_t<I> n, const T& x) const
{
I rollback{first};
try
{
for (; n-- > 0; ++first)
ranges::construct_at(std::addressof(*first), x);
return first;
}
catch (...) // rollback: destroy constructed elements
{
for (; rollback != first; ++rollback)
ranges::destroy_at(std::addressof(*rollback));
throw;
}
}
};

inline constexpr uninitialized_fill_n_fn uninitialized_fill_n{};

Examples

Main.cpp
#include <iostream>
#include <memory>
#include <string>

int main()
{
constexpr int n{3};
alignas(alignof(std::string)) char out[n * sizeof(std::string)];

try
{
auto first{reinterpret_cast<std::string*>(out)};
auto last = std::ranges::uninitialized_fill_n(first, n, "cppreference");

for (auto it{first}; it != last; ++it)
std::cout << *it << '\n';

std::ranges::destroy(first, last);
}
catch (...)
{
std::cout << "Exception!\n";
}
}
Output
cppreference
cppreference
cppreference
This article originates from this CppReference page. It was likely altered for improvements or editors' preference. Click "Edit this page" to see all changes made to this document.
Hover to see the original license.