Skip to main content

std::ranges::uninitialized_fill() algorithm

// (1)
I uninitialized_fill( I first, S last, const T& x );

// (2)
ranges::borrowed_iterator_t<R> uninitialized_fill( R&& r, 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&>
  • (1) std::constructible_from<ranges::range_value_t<R>, const T&>

With the helper types defined as follows:

template< class I, class O >
using uninitialized_fill_result = ranges::in_out_result<I, O>;
  • (1) Given N as ranges::distance(first, last):

    Constructs N copies of the given value x in an uninitialized memory area, designated by the range [first; last). The function has the effect equivalent to:

    for (; first != last; ++first)
    ::new (static_cast<void*>(std::addressof(*first)))
    std::remove_reference_t<std::iter_reference_t<I>>(x);

    return first;
    caution

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

  • (2) Same as (1), but uses r as the range, as if using ranges::begin(r) as first, and ranges::end(r) as last.

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

Parameters

first
last

The range of elements to fill.

r

The range of elements to fill.

value

The value to construct the elements with.

Return value

An iterator equal to last.

Complexity

Given N as ranges::distance(first, last):

O(N)

Exceptions

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

Possible implementation

uninitialized_fill(1) and uninitialized_fill(2)
struct uninitialized_fill_fn
{
template<no-throw-forward-iterator I, no-throw-sentinel-for<I> S, class T>
requires std::constructible_from<std::iter_value_t<I>, const T&>
I operator()(I first, S last, const T& x) const
{
I rollback{first};
try
{
for (; !(first == last); ++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;
}
}

template<no-throw-forward-range R, class T>
requires std::constructible_from<ranges::range_value_t<R>, const T&>
ranges::borrowed_iterator_t<R>
operator()(R&& r, const T& x) const
{
return (*this)(ranges::begin(r), ranges::end(r), x);
}
};

inline constexpr uninitialized_fill_fn uninitialized_fill{};

Examples

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

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

try
{
auto first{reinterpret_cast<std::string*>(out)};
auto last{first + n};
std::ranges::uninitialized_fill(first, last, "▄▀▄▀▄▀▄▀");

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

std::ranges::destroy(first, last);
}
catch(...)
{
std::cout << "Exception!\n";
}
}
Output
1 ▄▀▄▀▄▀▄▀
2 ▄▀▄▀▄▀▄▀
3 ▄▀▄▀▄▀▄▀
4 ▄▀▄▀▄▀▄▀
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() algorithm

// (1)
I uninitialized_fill( I first, S last, const T& x );

// (2)
ranges::borrowed_iterator_t<R> uninitialized_fill( R&& r, 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&>
  • (1) std::constructible_from<ranges::range_value_t<R>, const T&>

With the helper types defined as follows:

template< class I, class O >
using uninitialized_fill_result = ranges::in_out_result<I, O>;
  • (1) Given N as ranges::distance(first, last):

    Constructs N copies of the given value x in an uninitialized memory area, designated by the range [first; last). The function has the effect equivalent to:

    for (; first != last; ++first)
    ::new (static_cast<void*>(std::addressof(*first)))
    std::remove_reference_t<std::iter_reference_t<I>>(x);

    return first;
    caution

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

  • (2) Same as (1), but uses r as the range, as if using ranges::begin(r) as first, and ranges::end(r) as last.

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

Parameters

first
last

The range of elements to fill.

r

The range of elements to fill.

value

The value to construct the elements with.

Return value

An iterator equal to last.

Complexity

Given N as ranges::distance(first, last):

O(N)

Exceptions

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

Possible implementation

uninitialized_fill(1) and uninitialized_fill(2)
struct uninitialized_fill_fn
{
template<no-throw-forward-iterator I, no-throw-sentinel-for<I> S, class T>
requires std::constructible_from<std::iter_value_t<I>, const T&>
I operator()(I first, S last, const T& x) const
{
I rollback{first};
try
{
for (; !(first == last); ++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;
}
}

template<no-throw-forward-range R, class T>
requires std::constructible_from<ranges::range_value_t<R>, const T&>
ranges::borrowed_iterator_t<R>
operator()(R&& r, const T& x) const
{
return (*this)(ranges::begin(r), ranges::end(r), x);
}
};

inline constexpr uninitialized_fill_fn uninitialized_fill{};

Examples

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

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

try
{
auto first{reinterpret_cast<std::string*>(out)};
auto last{first + n};
std::ranges::uninitialized_fill(first, last, "▄▀▄▀▄▀▄▀");

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

std::ranges::destroy(first, last);
}
catch(...)
{
std::cout << "Exception!\n";
}
}
Output
1 ▄▀▄▀▄▀▄▀
2 ▄▀▄▀▄▀▄▀
3 ▄▀▄▀▄▀▄▀
4 ▄▀▄▀▄▀▄▀
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.