iter_move(s...d_iterator)(3)

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

okay bestie, welcome to the C++ Standard Libary manual page for iter_move(std::counted_iterator) β€” yes, the header is doing iter_move(s...d_iterator)(3) β€” section 3. This page is lowkey niche but highkey iconic, and we’re keeping every single detail. πŸ’…βœ¨

πŸ’– NAME πŸ’–

iter_move(std::counted_iterator) - iter_move(std::counted_iterator)

✨ Synopsis ✨

Since C++20 πŸŽ€

friend constexpr decltype(auto) iter_move( const
std::counted_iterator& i )
    noexcept(noexcept(ranges::iter_move(i.base())))

    requires std::input_iterator<I>;

Okay so here’s the tea: it casts the result of dereferencing the underlying iterator to its associated rvalue reference type. The function body is equivalent to return ranges::iter_move(i.base());. 🫢

Vibe check on lookup: this function is not visible to ordinary unqualified or qualified lookup, and it can only be found by argument-dependent lookup when std::counted_iterator<I> is an associated class of the arguments. That’s the ADL moment, iykyk. πŸ’«

🚨 If i.count() is equal to 0, the behavior is undefined. Not undefined as in β€œmystery”, undefined as in do-not. πŸ’€

🌸 Parameters 🌸

  • i β€” a source iterator adaptor.

πŸŽ€ Return value πŸŽ€

An rvalue reference or a prvalue temporary. That’s it, that’s the return. ✨

πŸ¦‹ Complexity πŸ¦‹

Constant. No extra drama, no hidden loops. πŸ’…

πŸ’œ Example πŸ’œ

// Run this code β€” and here’s the whole thing, copied with love and exact tokens:

// Run this code

        #include <iomanip>
        #include <iostream>
        #include <iterator>
        #include <string>
        #include <vector>

        void print(auto const& rem, auto const& v)
        {
            std::cout << rem << '[' << size(v) << "] {";
            for (char comma[]{0, ' ', 0}; auto const& s : v)
                std::cout << comma << std::quoted(s), *comma = ',';
            std::cout << "}\n";
        }

        int main()
        {
            std::vector<std::string> p{"Alpha", "Bravo", "Charlie"}, q;
            print("p", p);
            print("q", q);

            using RI =
       std::counted_iterator<std::vector<std::string>::iterator>;

            for (RI iter{p.begin(), 2}; iter != std::default_sentinel; ++iter)
                q.emplace_back(/* ADL */ iter_move(iter));

            print("p", p);
            print("q", q);
        }

πŸ“ Possible output πŸ“

p[3] {"Alpha", "Bravo", "Charlie"}
q[0] {}
p[3] {"", "", "Charlie"}
q[2] {"Alpha", "Bravo"}

πŸ”§ Defect reports πŸ”§

The following behavior-changing defect reports were applied retroactively to previously published C++ standards. πŸ› οΈ

  • LWG 3953 β€” applied to C++20. Behavior as published: the return type was changed to std::iter_rvalue_reference_t<I>; correct behavior: decltype(auto).

🌈 See also 🌈

  • iter_move (C++20) β€” casts the result of dereferencing an object to its associated rvalue reference type (customization point object).
  • iter_swap (C++20) β€” swaps the objects pointed to by two underlying iterators (function template).
  • move (C++11) β€” obtains an rvalue reference (function template).
  • move_if_noexcept (C++11) β€” obtains an rvalue reference if the move constructor does not throw (function template).
  • forward (C++11) β€” forwards a function argument (function template).
  • ranges::move (C++20) β€” moves a range of elements to a new location (niebloid).
  • ranges::move_backward (C++20) β€” moves a range of elements to a new location in backwards order (niebloid).

and that’s the whole page, bestie 🫢. Footer shoutout: source http://cppreference.com, version/date 2024.06.10, and the title tag iter_move(s...d_iterator)(3). Mwah πŸ’‹βœ¨

πŸ“¦ where this page comes from