std::iota(3)

πŸ“¦ version 2024.07.05, in nixpkgs unstable, opensuse-leap 16.0

πŸ’– std::iota(3) πŸ’–

okay bestie, pull up a chair because today we're talking about std::iota from the C++ Standard Library (that's the manual name, mwah, consider it folded in πŸŽ€). She's a tiny little algorithm with a big glow-up energy, and yes, iykyk.


✨ SYNOPSIS ✨

She lives in this header, bestie, don't forget it:

Defined in header <numeric>

And here's her signature, no cap:

template< class ForwardIt, class T >                          (since C++11)
void iota( ForwardIt first, ForwardIt last, T value );
                                                              (constexpr since C++20)

So what does she do? She fills the range [first, last) with values that go up one at a time, sequentially, starting with value and just... repeatedly evaluating ++value. That's it. That's the whole vibe. πŸ”₯

Here's the equivalent operation (assuming ++value returns the incremented value), so you can literally see her working):

*first   = value;
*++first = ++value;
*++first = ++value;
*++first = ++value;
// repeats until β€œlast” is reached

Now the serious part, so listen up bestie 🫢 β€” if any of these conditions is satisfied, your program is ill-formed:

  • T is not convertible to the value type of ForwardIt.
  • The expression ++val is ill-formed, where val is a variable of type T.
🚨 like, actually ill-formed. not a warning, not a "eh it'll probably work", not a runtime oopsie. the program is bad and the compiler is allowed to be dramatic about it. periodt.

🌸 PARAMETERS 🌸

  • first, last β€” the range of elements to fill with sequentially increasing values starting with value. πŸ’«
  • value β€” initial value to store. this is where the countdown... er, count-up... starts. πŸŽ€

⭐ COMPLEXITY ⭐

Exactly std::distance(first, last) increments and assignments. Not one more, not one less. she's efficient like that. πŸ’…


πŸ¦‹ POSSIBLE IMPLEMENTATION πŸ¦‹

look at her, she's so small and perfect, I'm obsessed:

template<class ForwardIt, class T>
constexpr // since C++20
void iota(ForwardIt first, ForwardIt last, T value)
{
    for (; first != last; ++first, ++value)
        *first = value;
}

πŸ‘‘ NOTES πŸ‘‘

Fun lore drop, bestie: the function is named after the integer function ⍳ from the programming language APL. 🧚 Cute, right? It was one of the STL components that were not included in C++98, but it made it into the standard library in C++11. So she's a late bloomer who absolutely ate. 🌈


πŸ“ EXAMPLE πŸ“

The following example applies std::shuffle to a vector of std::lists' iterators. std::iota is used to populate containers. 🫢

// Run this code

#include <algorithm>
#include <iomanip>
#include <iostream>
#include <list>
#include <numeric>
#include <random>
#include <vector>

class BigData // inefficient to copy
{
    int data[1024]; /* some raw data */
public:
    explicit BigData(int i = 0) { data[0] = i; /* ... */ }
    operator int() const { return data[0]; }
    BigData& operator=(int i) { data[0] = i; return *this; }
    /* ... */
};

int main()
{
    std::list<BigData> l(10);
    std::iota(l.begin(), l.end(), -4);

    std::vector<std::list<BigData>::iterator> v(l.size());
    std::iota(v.begin(), v.end(), l.begin());
    // Vector of iterators (to original data) is used to avoid expensive copying,
    // and because std::shuffle (below) cannot be applied to a std::list directly.

    std::shuffle(v.begin(), v.end(), std::mt19937{std::random_device{}()});

    std::cout << "Original contents of the list l:\t";
    for (const auto& n : l)
        std::cout << std::setw(2) << n << ' ';
    std::cout << '\n';

    std::cout << "Contents of l, viewed via shuffled v:\t";
    for (const auto i : v)
        std::cout << std::setw(2) << *i << ' ';
    std::cout << '\n';
}

πŸ’œ Possible output πŸ’œ

Original contents of the list l:        -4 -3 -2 -1  0  1  2  3  4  5
Contents of l, viewed via shuffled v:   -1  5 -4  0  2  1  4 -2  3 -3

(yes the shuffle output is random, don't come for me, it says possible output for a reason 😭)


πŸŽ€ SEE ALSO πŸŽ€

  • ranges::iota_view (C++20) β€” a view consisting of a sequence generated by repeatedly incrementing an initial value (class template)
  • views::iota (C++20) β€” (customization point object)
  • fill β€” copy-assigns the given value to every element in a range (function template)
  • ranges::fill (C++20) β€” assigns a range of elements a certain value (niebloid)
  • generate β€” assigns the results of successive function calls to every element in a range (function template)
  • ranges::generate (C++20) β€” saves the result of a function in a range (niebloid)
  • ranges::iota (C++23) β€” fills a range with successive increments of the starting value (niebloid)

okay that's the whole page bestie, go forth and iota responsibly πŸ’…βœ¨

This masterpiece was brought to you by http://cppreference.com, dated 2024.06.10 β€” and the page itself is std::iota(3), in case you forgot where you were. mwah! πŸ’–πŸ¦‹πŸŒΈ

πŸ“¦ where this page comes from