iter_move(s...on_iterator)(3)

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

πŸ’… iter_move(std::common_iterator) β€” C++ Standard Library, section 3 πŸŽ€

okay so bestie, buckle up, because this one is a tiny little function with a whole lot of ✨rules✨ around it. It lives in the C++ Standard Library (manual section 3, iykyk) and it's called iter_move(std::common_iterator) β€” yes the title and the NAME are literally the same thing, she's not beating the copy-paste allegations but she's iconic so we move πŸ’…

✨ NAME ✨

iter_move(std::common_iterator) β€” literally just iter_move(std::common_iterator), that's the whole name, slay.

🌸 Synopsis 🌸

friend constexpr decltype(auto) iter_move( const std::common_iterator& i )
    noexcept(noexcept(ranges::iter_move(std::declval<const I&>())))
        requires std::input_iterator<I>;

since C++20 🫢

So what does she do? She casts the result of dereferencing the underlying iterator to its associated rvalue reference type. That's it. That's the job. Main character energy, minimal effort πŸ’œ

The function body is equivalent to:

return std::ranges::iter_move(std::get<I>(i.var));
🚨 Important vibe check: this function is not visible to ordinary unqualified or qualified lookup. Like, she's not on the guest list for normal name searches at all. She can only be found by argument-dependent lookup (ADL) when std::common_iterator<I, S> is an associated class of the arguments. iykyk πŸ”₯
πŸ’€ And another one: if i.var does not hold an I object (i.e. an iterator), the behavior is undefined. Not "kinda weird", not "returns garbage" β€” undefined. Do not test her. πŸ™ˆ

πŸ¦‹ Parameters πŸ¦‹

  • i β€” a source iterator adaptor

That's one (1) parameter, she's low maintenance πŸ’–

⭐ Return value ⭐

An rvalue reference or a prvalue temporary. Both are valid, she contains multitudes ✨

πŸŽ€ Complexity πŸŽ€

Constant. O(1) baby, no loops, no drama, we love a consistent queen πŸ‘‘

🌈 Example 🌈

// 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 (int o{}; auto const& s : v)
        std::cout << (o++ ? ", " : "") << std::quoted(s);
    std::cout << " }\n";
}

int main()
{
    std::vector<std::string> p{"Andromeda", "Cassiopeia", "Phoenix"}, q;
    print("p", p);
    print("q", q);

    using CTI = std::counted_iterator<std::vector<std::string>::iterator>;
    using CI = std::common_iterator<CTI, std::default_sentinel_t>;
    CI last{std::default_sentinel};

    for (CI first{{p.begin(), 2}}; first != last; ++first)
        q.emplace_back(/* ADL */ iter_move(first));

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

πŸ“ Possible output πŸ“

p[3] { "Andromeda", "Cassiopeia", "Phoenix" }
q[0] {  }
p[3] { "", "", "Phoenix" }
q[2] { "Andromeda", "Cassiopeia" }

look at those strings getting moved out and left as "" β€” she ate and left no crumbs 😭πŸ”₯


🧚 Defect reports 🧚

The following behavior-changing defect reports were applied retroactively to previously published C++ standards. (Retroactively!! she went back in time to fix her mistakes, obsessed 🫢)

  • LWG 3953 β€” applied to C++20
    • Behavior as published: the return type was 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_move (C++20) β€” casts the result of dereferencing the underlying iterator to its associated rvalue reference type (function)
  • 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, every flag, every requirement, every undefined-behavior warning, nothing skipped, periodt πŸ’…

okay bye, this doc was served to you fresh from http://cppreference.com, dated 2024.06.10, page iter_move(std::common_iterator)(3) β€” mwah, go write some ADL-correct code πŸŽ€πŸ’–πŸ¦‹

πŸ“¦ where this page comes from