<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/138735>138735</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [clang-tidy] Check request: modernize-use-structured-binding
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          denzor200
      </td>
    </tr>
</table>

<pre>
    
C++17 suggests us structured binding feature as a convenient way to decompose composite objects into individual variables.
Needs a check that will find creations of a tuple-like which was assigned from a returned value. The check will show warning to change it to use structured binding.
Also the check will provide fix-it in the case when it's possible to deduce names for future decomposed variables.

BEFORE:
```
const auto results = mapping.try_emplace("hello!");   // WARNING AND FIX-IT
const iterator& it = results.first;
const bool succeed = results.second;
```

AFTER:
```
const auto [it, succeed] = mapping.try_emplace("hello!");
```

The check should also cover `for` statements:

BEFORE:
```
for (const auto& node : mapping) { // WARNING AND FIX-IT
    const std::string& key = node.first;
 const A& value = node.second;
    // ...
}
```

AFTER:
```
for (const auto& [key, value] : mapping) {
    // ...
}
```

The check must respect original result's cv-ref modifiers.

BEFORE:
```
const auto& results = mapping.try_emplace("hello!");  // WARNING AND FIX-IT
const iterator& it = results.first;
bool succeed = results.second;
```

AFTER:
```
const auto& [it, succeed] = mapping.try_emplace("hello!");
```

Keep in mind that the check will not provide fix-it in the case when the changed code will not be compiled - just a warning would be enough:

BEFORE:
```
const auto results = mapping.try_emplace("hello!");   // WARNING
const iterator& it = results.first;
bool succeed = results.second;
succeed = true;
```

INCORRECT AFTER:
```
const auto [it, succeed] = mapping.try_emplace("hello!");
succeed = true; // BAD - assignment of read-only variable 'succeed'
```

Also the check will not provide fix-it in the case when it's impossible to deduce names - just a warning would be enough:
```
const auto results = mapping.try_emplace("hello!");   // WARNING
if (results.second) {
    handle_inserted(results.first);
}
// no name deduced
```

In the case when it's impossible to use structured-binding no warning must be provided:
```
const auto results = mapping.try_emplace("hello!");
handle_inserted(results);
```

Reassignment of potentially decomposed variables must be considered as impossibility to use structured binding - no warning, this is a job for [modernize-use-std-tie-to-decompose-result](https://github.com/llvm/llvm-project/issues/138732).

BEFORE:
```
const auto pos1 = get_position();                                 // WARNING AND FIX-IT
float x = pos.1first;
float y = pos1.second;
// ...

const auto pos2 = get_position2();
x = pos2.first;
y = pos2.second;
```

AFTER:
```
auto [x, y] = get_position();
// ...

const auto pos2 = get_position2();
x = pos2.first;
y = pos2.second;
```

</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzEV9tu4zYQ_Rr6ZSBDpizbefCDnMRFUCALBAHatwUljixuaFIlR_Z6v74gfc86WW-7aYMAvoicy5kzZ8bCe7UwiFOWz1h-1xMdNdZNJZpv1vE07ZVWbqYsLW4ZnzE-G4zBd4sFevLQefDkuoo6hxJKZaQyC6hRhC9AeBBQWbNCo9AQrMUGyILEyi5b6xG2r4oQbPkFK_KgDFkIZlZKdkLDSjglSo2-z9LiEVFGkw1WL0CNIFgrraFWRkLlUJCyxoOtQQB1rcZEqxeEdaOqBtYhmm2qEmpnlyDAIXUufF4J3WEfnhvcGY92fWPXsBbOhKTIQtUIs0BQFD50Hi_kHsIstLdA56ZaZ1dKItTqa6IIlNkeED6EhwYUMT720FrvValxC5PsKgQjluihtg7qLqJ6gE-eo8PSYnY___R0z7Lwno3S3X9aVNZ4AtGRBYe-0-SBZXewFG0bYia3-YzLVosKGZ8wzhvU2jI-YJwzfsOyGQAwPmd8Dn8UT48Pj79B8XgH84c_k4fng31F6ARZx_goYBQ87Lz1a-U8sWx2OFtaq8F3VYUoz056rKyR26OnKQRc58_3T-8mx_JZAPJ2b5nldz-Z6Pdej5zwje20BBHKW9kVOmCjtLaOjVLwJAiXaMjvAny7GKGUjE-OYQe8jJUILCv2oTJ-A2w8exd1AICtFU8y-MkKTy5eHsELbmLqwfAp_LsbRTgTWX88dQo9HCve70d2je-ursjFDFk-e8FNKE50uy3N63yv9nysyrLzFNjTYkVgnVooI_SOTrGnqlXisIallapW6K7vlRD1P22XX9UtH9Inu3L88lb5HbEN0rYMehzl-ZUKGks_VMLtlSC0EqrQFYeb5XZgKI0SEvgS6i4O8ryOvVkioLHdovlhF_56SfyIyp4-J9fhRdgfHm8_PT3d3z7Df6SQF6LaYzEr7iDZzdkgh2EYOxQysUZvDvMKQmPuAuDjCwy-MEGv4c5uiqrlm3P0St58NFFUHQTyVcXPJLARRmr8rIxHRwGmyTmHDi24VcetA2NjmruU5QWqXIXY-WqT7Nc6Yw-oRdEtcV8Q-QGwsbR4E4O3BOgJz5nXWkJDSmi9ubg2HfII0SqJYZETRzSUVrR5e9eD5ASS0FPUKA8qbKhfbBlXNpbPllaiM-obJp3HxJNMSGFCNjkElOyGVX7H-KQhauMOESu6UNR0Zb-yS8bnWq_2L0nrbFiYGZ8r7zv0jM8H2WScBfCuXwZb6wexLAukz3ETV9bEeuyI-_7fe0Ou1lYQfI3WW-v7gxPp2z7b7J8NzofZ2ex_HS7_Llx-iJelxcEfP5XazfHbnx-be9n8Giq82evlRcD-t-h7cprJm-xG9HA6GA9HeT4a3Yx6zXQgaszLrBrKEnEwGQ7z0U2WpxOJdZmPh3lPTXnK8zRPR4NJNhmM-sPJBKssH6YjOUnrAWfDFJdC6X6gXd-6RS8SbhrZlve0KFH7_U9HN43kLLuFZ8NUK0_-eI8U6fgjs9LCLBJSMqJ5GyXe4V8dhowLeN0wr3Wo1zk9_ZdtkvdWU_53AAAA__8Lp6Ay">