| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // See [Copy elision](https://en.cppreference.com/w/cpp/language/copy_elision) | ||
| 2 | // See [Return value optimizations](https://www.fluentcpp.com/2016/11/28/return-value-optimizations/) | ||
| 3 | // See [Understanding when not to std::move in C++](https://developers.redhat.com/blog/2019/04/12/understanding-when-not-to-stdmove-in-c) | ||
| 4 | // See [How to Return Several Values from a Function in C++](https://www.fluentcpp.com/2021/07/09/how-to-return-several-values-from-a-function-in-c) | ||
| 5 | |||
| 6 | #include "Verbose.hpp" | ||
| 7 | #include <iostream> | ||
| 8 | #include <tuple> | ||
| 9 | |||
| 10 | // A class that can be moved but not copied. | ||
| 11 | class Uncopyable { | ||
| 12 | public: | ||
| 13 | 4 | Uncopyable() noexcept = default; // default constructor | |
| 14 | Uncopyable(Uncopyable&&) noexcept = default; // move constructor | ||
| 15 | 1 | Uncopyable& operator=(Uncopyable&&) noexcept = default; // move assignment | |
| 16 | 8 | virtual ~Uncopyable() noexcept = default; // destructor | |
| 17 | |||
| 18 | Uncopyable(const Uncopyable&) = delete; // no copy constructor | ||
| 19 | Uncopyable& operator=(const Uncopyable&) = delete; // no copy assignment | ||
| 20 | }; | ||
| 21 | |||
| 22 | // A class that can be copied but not moved. | ||
| 23 | class Unmovable { | ||
| 24 | public: | ||
| 25 | 3 | Unmovable() noexcept = default; // default constructor | |
| 26 | Unmovable(const Unmovable&) = default; // copy constructor | ||
| 27 | 1 | Unmovable& operator=(const Unmovable&) = default; // copy assignment | |
| 28 | 6 | virtual ~Unmovable() noexcept = default; // destructor | |
| 29 | |||
| 30 | Unmovable(Unmovable&&) noexcept = delete; // no move constructor | ||
| 31 | Unmovable& operator=(Unmovable&&) noexcept = delete; // no move assignment | ||
| 32 | }; | ||
| 33 | |||
| 34 | // An unrelated class that is convertible to Verbose. | ||
| 35 | class Convertible { | ||
| 36 | public: | ||
| 37 | 2 | operator Verbose<>() { | |
| 38 | 2 | std::cout << "Convertible: conversion to Verbose this=" << this | |
| 39 | 2 | << std::endl; | |
| 40 |
2/4✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
|
8 | return Verbose<>{"Converted to Verbose"}; // rvo? |
| 41 | } | ||
| 42 | }; | ||
| 43 | |||
| 44 | // A derived class. | ||
| 45 | class Derived : public Verbose<> { | ||
| 46 | public: | ||
| 47 | 3 | Derived() noexcept : Verbose<>{"Derived"} {} | |
| 48 | }; | ||
| 49 | |||
| 50 | // Unnamed value constructed in return statement. | ||
| 51 |
2/4✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
|
8 | Verbose<> rvo() { return Verbose<>{"unnamed"}; } |
| 52 | |||
| 53 | // Unnamed value constructed in return statement. | ||
| 54 | // Copy constructor need not be available. | ||
| 55 |
2/4✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
|
4 | Verbose<Uncopyable> rvo_uncopyable() { return Verbose<Uncopyable>{"unnamed"}; } |
| 56 | |||
| 57 | #if __cplusplus >= 201703L // since C++17 | ||
| 58 | |||
| 59 | // Unnamed value constructed in return statement. | ||
| 60 | // Move constructor need not be available. | ||
| 61 |
2/4✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
|
4 | Verbose<Unmovable> rvo_unmovable() { return Verbose<Unmovable>{"unnamed"}; } |
| 62 | |||
| 63 | #endif // C++17 | ||
| 64 | |||
| 65 | // Unnamed values constructed in all return statements. | ||
| 66 | 1 | Verbose<> rvo_conditional(int x) { | |
| 67 |
3/6✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
|
3 | if (x % 2 == 0) { return Verbose<>{"even"}; } |
| 68 | ✗ | else { return Verbose<>{"odd"}; } | |
| 69 | } | ||
| 70 | |||
| 71 | // Unnamed value constructed from return value in return statement. | ||
| 72 | 1 | Verbose<> rvo_chained() { return Verbose<>{rvo()}; } | |
| 73 | |||
| 74 | #if __cplusplus >= 201402L // since C++14 | ||
| 75 | |||
| 76 | // Unnamed tuple of unnamed values constructed in return statement. | ||
| 77 | 3 | auto rvo_tuple() { return std::tuple<Verbose<>, Verbose<>>{"first", "second"}; } | |
| 78 | |||
| 79 | #endif // C++14 | ||
| 80 | |||
| 81 | // Unique named return value. | ||
| 82 | 2 | Verbose<> nrvo() { | |
| 83 |
2/4✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
|
6 | auto result = Verbose<>{"unique"}; |
| 84 | 2 | return result; | |
| 85 | } | ||
| 86 | |||
| 87 | // Unique named movable return value. | ||
| 88 | // Copy constructor not available. | ||
| 89 | // How does this work ?! | ||
| 90 | 1 | Verbose<Uncopyable> nrvo_uncopyable() { | |
| 91 |
2/4✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
|
3 | auto result = Verbose<Uncopyable>{"unique"}; |
| 92 | 1 | return result; | |
| 93 | } | ||
| 94 | |||
| 95 | // Unique named copyable return value. | ||
| 96 | // Fail! Move constructor not available! Does not compile! | ||
| 97 | /* | ||
| 98 | Unmovable nrvo_unmovable() | ||
| 99 | { | ||
| 100 | auto result Unmovable { "unique" }; | ||
| 101 | return result; | ||
| 102 | } | ||
| 103 | */ | ||
| 104 | |||
| 105 | // Unique named return value in all return statements. | ||
| 106 | 1 | Verbose<> nrvo_conditional(int x) { | |
| 107 |
2/4✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
|
3 | auto result = Verbose<>{"unknown"}; |
| 108 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (x % 2 == 0) { |
| 109 | ✗ | result.name() = "even"; | |
| 110 | ✗ | return result; | |
| 111 | } | ||
| 112 | else { | ||
| 113 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | result.name() = "odd"; |
| 114 | 1 | return result; | |
| 115 | } | ||
| 116 | ✗ | } | |
| 117 | |||
| 118 | // Unique named return value constructed from return value. | ||
| 119 | 1 | Verbose<> nrvo_chained() { | |
| 120 | 1 | auto result = Verbose<>{nrvo()}; | |
| 121 | 1 | return result; | |
| 122 | } | ||
| 123 | |||
| 124 | #if __cplusplus >= 201402L // since C++14 | ||
| 125 | |||
| 126 | // Unique named tuple return value. | ||
| 127 | 2 | auto nrvo_tuple_good() { | |
| 128 | 2 | auto result = std::tuple<Verbose<>, Verbose<>>{"one", "two"}; | |
| 129 | 2 | auto& v1 = std::get<0>(result); | |
| 130 | 2 | auto& v2 = std::get<1>(result); | |
| 131 |
1/2✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
|
2 | v1.name() = "first"; |
| 132 |
1/2✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
|
2 | v2.name() = "second"; |
| 133 | 2 | return result; | |
| 134 | ✗ | } | |
| 135 | |||
| 136 | #endif // C++14 | ||
| 137 | |||
| 138 | #if __cplusplus >= 201703L // since C++17 | ||
| 139 | |||
| 140 | // Unique named tuple return value. | ||
| 141 | 2 | auto nrvo_tuple_better() { | |
| 142 | 2 | auto result = std::tuple<Verbose<>, Verbose<>>{"one", "two"}; | |
| 143 | 2 | auto& [v1, v2] = result; | |
| 144 |
1/2✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
|
2 | v1.name() = "first"; |
| 145 |
1/2✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
|
2 | v2.name() = "second"; |
| 146 | 2 | return result; | |
| 147 | ✗ | } | |
| 148 | |||
| 149 | #endif // C++17 | ||
| 150 | |||
| 151 | #if __cplusplus >= 201402L // since C++14 | ||
| 152 | |||
| 153 | // Fail! Named tuple of named values. | ||
| 154 | ✗ | auto nrvo_tuple_bad() { | |
| 155 | ✗ | auto v1 = Verbose<>{"first"}; | |
| 156 | ✗ | auto v2 = Verbose<>{"second"}; | |
| 157 | ✗ | auto result = std::make_tuple(v1, v2); | |
| 158 | ✗ | return result; | |
| 159 | ✗ | } | |
| 160 | |||
| 161 | // Unique named return value using a local, unnamed struct. | ||
| 162 | // Pros: | ||
| 163 | // + Returned values can have meaningful names, unlike std::tuple. | ||
| 164 | // + No need to unpack returned values with std::get or std::tie. | ||
| 165 | // + Works with structured binding, just like std::tuple. | ||
| 166 | // Cons: | ||
| 167 | // - Cannot be declared as a return type, unlike std::tuple, | ||
| 168 | // making the number of and types of returned values unclear. | ||
| 169 | // - Requires return type deduction. (C++14) | ||
| 170 | // * Cannot be used for virtual member functions. | ||
| 171 | // * Implemtation must be in same translation unit as declaration. | ||
| 172 | 2 | auto nrvo_struct() { | |
| 173 | struct { | ||
| 174 | Verbose<> first{"first"}; | ||
| 175 | Verbose<> second{"second"}; | ||
| 176 | 2 | } result; | |
| 177 | 2 | return result; | |
| 178 | } | ||
| 179 | |||
| 180 | #endif // C++14 | ||
| 181 | |||
| 182 | // Non-unique return values. | ||
| 183 | // This actually works with LLVM ?! | ||
| 184 | 1 | Verbose<> nrvo_not_unique(int x) { | |
| 185 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (x % 2 == 0) { |
| 186 | ✗ | auto even = Verbose<>{"even"}; | |
| 187 | ✗ | return even; | |
| 188 | ✗ | } | |
| 189 | else { | ||
| 190 |
2/4✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
|
3 | auto odd = Verbose<>{"odd"}; |
| 191 | 1 | return odd; | |
| 192 | 1 | } | |
| 193 | } | ||
| 194 | |||
| 195 | // Fail! Return value is function parameter. | ||
| 196 | 1 | Verbose<> nrvo_value_parameter(Verbose<> v) { return v; } | |
| 197 | |||
| 198 | // Fail! Return value is function parameter. | ||
| 199 | 1 | Verbose<> nrvo_const_ref_parameter(const Verbose<>& v) { return v; } | |
| 200 | |||
| 201 | // Fail! Return value is function parameter. | ||
| 202 | 2 | Verbose<> nrvo_move_parameter(Verbose<>&& v) { return std::move(v); } | |
| 203 | |||
| 204 | // Fail! Unnamed value assigned to output parameter. | ||
| 205 | 1 | void rvo_output_parameter(Verbose<Uncopyable>& result) { | |
| 206 |
2/4✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
|
3 | result = Verbose<Uncopyable>{"parameter"}; |
| 207 | 1 | } | |
| 208 | |||
| 209 | #if __cplusplus >= 201703L // since C++17 | ||
| 210 | |||
| 211 | // Fail! Unique named value assigned to output parameter. | ||
| 212 | 1 | void nrvo_output_parameter(Verbose<Unmovable>& result) { | |
| 213 |
2/4✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
|
3 | auto v = Verbose<Unmovable>{"parameter"}; |
| 214 |
1/2✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | result = v; |
| 215 | 2 | } | |
| 216 | |||
| 217 | #endif // C++17 | ||
| 218 | |||
| 219 | // Conversion operator is invoked implicitly. | ||
| 220 | // No copy or move operation is invoked, with or wihtout std::move(). | ||
| 221 | // Using std::move() produces a GNU (but not LLVM) compiler warning. | ||
| 222 | 1 | Verbose<> implicit_conversion() { | |
| 223 | 1 | auto c = Convertible{}; | |
| 224 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | return c; // std::move() has no effect |
| 225 | } | ||
| 226 | |||
| 227 | // Conversion operator is invoked explicitly. | ||
| 228 | // No copy or move operation is invoked, with or without std::move(). | ||
| 229 | // Using std::move() does not produce a compiler warning. | ||
| 230 | 1 | Verbose<> explicit_conversion() { | |
| 231 | 1 | auto c = Convertible{}; | |
| 232 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | return static_cast<Verbose<>>(c); // std::move() has no effect |
| 233 | } | ||
| 234 | |||
| 235 | // Convert to base type. | ||
| 236 | // Copy or move constructor is invoked, with or without std::move(). | ||
| 237 | // Using std::move() produces a GNU (but not LLVM) compiler warning. | ||
| 238 | 1 | Verbose<> class_conversion() { | |
| 239 | 1 | auto d = Derived{}; | |
| 240 | 1 | return d; // std::move() has no effect | |
| 241 | 1 | } | |
| 242 | |||
| 243 | //////////////////////////////////////////////////////////////////////////////// | ||
| 244 | |||
| 245 | #include <gmock/gmock.h> | ||
| 246 | |||
| 247 | using namespace testing; | ||
| 248 | using namespace testing::internal; | ||
| 249 | |||
| 250 | constexpr auto even_number{2}; | ||
| 251 | constexpr auto odd_number{17}; | ||
| 252 | |||
| 253 | 8 | TEST(CopyElision, rvo) { | |
| 254 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | CaptureStdout(); |
| 255 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | auto v = rvo(); |
| 256 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | auto actual = GetCapturedStdout(); |
| 257 |
7/20✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
✓ Branch 24 taken 1 times.
✗ Branch 25 not taken.
✗ Branch 37 not taken.
✓ Branch 38 taken 1 times.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
|
2 | EXPECT_THAT(actual, Not(AnyOf(HasSubstr("copy"), HasSubstr("move")))); |
| 258 |
3/6✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
|
2 | std::cout << std::endl << actual << std::endl; |
| 259 | 4 | } | |
| 260 | |||
| 261 | 8 | TEST(CopyElision, rvo_uncopyable) { | |
| 262 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | CaptureStdout(); |
| 263 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | auto u = rvo_uncopyable(); |
| 264 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | auto actual = GetCapturedStdout(); |
| 265 |
7/20✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
✓ Branch 24 taken 1 times.
✗ Branch 25 not taken.
✗ Branch 37 not taken.
✓ Branch 38 taken 1 times.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
|
2 | EXPECT_THAT(actual, Not(AnyOf(HasSubstr("copy"), HasSubstr("move")))); |
| 266 |
3/6✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
|
2 | std::cout << std::endl << actual << std::endl; |
| 267 | 4 | } | |
| 268 | |||
| 269 | #if __cplusplus >= 201703L // since C++17 | ||
| 270 | |||
| 271 | 8 | TEST(CopyElision, rvo_unmovable) { | |
| 272 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | CaptureStdout(); |
| 273 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | auto u = rvo_unmovable(); |
| 274 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | auto actual = GetCapturedStdout(); |
| 275 |
7/20✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
✓ Branch 24 taken 1 times.
✗ Branch 25 not taken.
✗ Branch 37 not taken.
✓ Branch 38 taken 1 times.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
|
2 | EXPECT_THAT(actual, Not(AnyOf(HasSubstr("copy"), HasSubstr("move")))); |
| 276 |
3/6✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
|
2 | std::cout << std::endl << actual << std::endl; |
| 277 | 4 | } | |
| 278 | |||
| 279 | #endif // C++17 | ||
| 280 | |||
| 281 | 8 | TEST(CopyElision, rvo_conditional) { | |
| 282 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | CaptureStdout(); |
| 283 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | auto v = rvo_conditional(even_number); |
| 284 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | auto actual = GetCapturedStdout(); |
| 285 |
7/20✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
✓ Branch 24 taken 1 times.
✗ Branch 25 not taken.
✗ Branch 37 not taken.
✓ Branch 38 taken 1 times.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
|
2 | EXPECT_THAT(actual, Not(AnyOf(HasSubstr("copy"), HasSubstr("move")))); |
| 286 |
4/14✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
✗ Branch 19 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
|
2 | EXPECT_THAT(v.name(), StrEq("even")); |
| 287 |
3/6✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
|
2 | std::cout << std::endl << actual << std::endl; |
| 288 | 4 | } | |
| 289 | |||
| 290 | 8 | TEST(CopyElision, rvo_chained) { | |
| 291 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | CaptureStdout(); |
| 292 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | auto v = rvo_chained(); |
| 293 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | auto actual = GetCapturedStdout(); |
| 294 |
7/20✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
✓ Branch 24 taken 1 times.
✗ Branch 25 not taken.
✗ Branch 37 not taken.
✓ Branch 38 taken 1 times.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
|
2 | EXPECT_THAT(actual, Not(AnyOf(HasSubstr("copy"), HasSubstr("move")))); |
| 295 |
3/6✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
|
2 | std::cout << std::endl << actual << std::endl; |
| 296 | 4 | } | |
| 297 | |||
| 298 | 8 | TEST(CopyElision, nrvo) { | |
| 299 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | CaptureStdout(); |
| 300 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | auto v = nrvo(); |
| 301 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | auto actual = GetCapturedStdout(); |
| 302 |
7/20✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
✓ Branch 24 taken 1 times.
✗ Branch 25 not taken.
✗ Branch 37 not taken.
✓ Branch 38 taken 1 times.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
|
2 | EXPECT_THAT(actual, Not(AnyOf(HasSubstr("copy"), HasSubstr("move")))); |
| 303 |
3/6✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
|
2 | std::cout << std::endl << actual << std::endl; |
| 304 | 4 | } | |
| 305 | |||
| 306 | 8 | TEST(CopyElision, nrvo_uncopyable) { | |
| 307 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | CaptureStdout(); |
| 308 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | auto v = nrvo_uncopyable(); |
| 309 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | auto actual = GetCapturedStdout(); |
| 310 |
7/20✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
✓ Branch 24 taken 1 times.
✗ Branch 25 not taken.
✗ Branch 37 not taken.
✓ Branch 38 taken 1 times.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
|
2 | EXPECT_THAT(actual, Not(AnyOf(HasSubstr("copy"), HasSubstr("move")))); |
| 311 |
3/6✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
|
2 | std::cout << std::endl << actual << std::endl; |
| 312 | 4 | } | |
| 313 | |||
| 314 | 8 | TEST(CopyElision, nrvo_conditional) { | |
| 315 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | CaptureStdout(); |
| 316 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | auto v = nrvo_conditional(odd_number); |
| 317 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | auto actual = GetCapturedStdout(); |
| 318 |
7/20✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
✓ Branch 24 taken 1 times.
✗ Branch 25 not taken.
✗ Branch 37 not taken.
✓ Branch 38 taken 1 times.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
|
2 | EXPECT_THAT(actual, Not(AnyOf(HasSubstr("copy"), HasSubstr("move")))); |
| 319 |
4/14✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
✗ Branch 19 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
|
2 | EXPECT_THAT(v.name(), StrEq("odd")); |
| 320 |
3/6✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
|
2 | std::cout << std::endl << actual << std::endl; |
| 321 | 4 | } | |
| 322 | |||
| 323 | 8 | TEST(CopyElision, nrvo_chained) { | |
| 324 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | CaptureStdout(); |
| 325 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | auto v = nrvo_chained(); |
| 326 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | auto actual = GetCapturedStdout(); |
| 327 |
7/20✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
✓ Branch 24 taken 1 times.
✗ Branch 25 not taken.
✗ Branch 37 not taken.
✓ Branch 38 taken 1 times.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
|
2 | EXPECT_THAT(actual, Not(AnyOf(HasSubstr("copy"), HasSubstr("move")))); |
| 328 |
3/6✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
|
2 | std::cout << std::endl << actual << std::endl; |
| 329 | 4 | } | |
| 330 | |||
| 331 | 8 | TEST(CopyElision, nrvo_not_unique) { | |
| 332 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | CaptureStdout(); |
| 333 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | auto v = nrvo_not_unique(odd_number); |
| 334 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | auto actual = GetCapturedStdout(); |
| 335 | #ifdef __clang__ | ||
| 336 | // LLVM compiler performs NRVO | ||
| 337 | EXPECT_THAT(actual, Not(AnyOf(HasSubstr("copy"), HasSubstr("move")))); | ||
| 338 | #else // not __clang__ | ||
| 339 | // Other compilers do not | ||
| 340 |
6/18✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 21 not taken.
✗ Branch 31 not taken.
✓ Branch 32 taken 1 times.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
|
2 | EXPECT_THAT(actual, AnyOf(HasSubstr("copy"), HasSubstr("move"))); |
| 341 | #endif // __clang__ | ||
| 342 |
4/14✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
✗ Branch 19 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
|
2 | EXPECT_THAT(v.name(), EndsWith("odd")); |
| 343 |
3/6✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
|
2 | std::cout << std::endl << actual << std::endl; |
| 344 | 4 | } | |
| 345 | |||
| 346 | 8 | TEST(CopyElision, nrvo_parameter) { | |
| 347 |
2/4✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
|
6 | auto p = Verbose<>{"local"}; |
| 348 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | CaptureStdout(); |
| 349 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
2 | auto v1 = nrvo_value_parameter(p); |
| 350 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | auto actual = GetCapturedStdout(); |
| 351 |
6/18✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 21 not taken.
✗ Branch 31 not taken.
✓ Branch 32 taken 1 times.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
|
2 | EXPECT_THAT(actual, AnyOf(HasSubstr("copy"), HasSubstr("move"))); |
| 352 |
3/6✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
|
2 | std::cout << std::endl << actual << std::endl; |
| 353 | |||
| 354 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | CaptureStdout(); |
| 355 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | auto v2 = nrvo_const_ref_parameter(p); |
| 356 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | actual = GetCapturedStdout(); |
| 357 |
6/18✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 21 not taken.
✗ Branch 31 not taken.
✓ Branch 32 taken 1 times.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
|
2 | EXPECT_THAT(actual, AnyOf(HasSubstr("copy"), HasSubstr("move"))); |
| 358 |
3/6✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
|
2 | std::cout << std::endl << actual << std::endl; |
| 359 | |||
| 360 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | CaptureStdout(); |
| 361 | 4 | auto v3 = nrvo_move_parameter(std::move(p)); | |
| 362 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | actual = GetCapturedStdout(); |
| 363 |
6/18✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 21 not taken.
✗ Branch 31 not taken.
✓ Branch 32 taken 1 times.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
|
2 | EXPECT_THAT(actual, AnyOf(HasSubstr("copy"), HasSubstr("move"))); |
| 364 |
3/6✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
|
2 | std::cout << std::endl << actual << std::endl; |
| 365 | 4 | } | |
| 366 | |||
| 367 | #if __cplusplus >= 201703L // since C++17 | ||
| 368 | |||
| 369 | 8 | TEST(CopyElision, output_parameter) { | |
| 370 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
6 | auto name = std::string{"local"}; |
| 371 |
2/4✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
|
2 | auto p1 = Verbose<Uncopyable>{name}; |
| 372 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | CaptureStdout(); |
| 373 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | rvo_output_parameter(p1); |
| 374 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | auto actual = GetCapturedStdout(); |
| 375 |
5/16✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✗ Branch 26 not taken.
✓ Branch 27 taken 1 times.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
|
2 | EXPECT_THAT(p1.name(), Not(StrEq(name))); |
| 376 |
6/18✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 21 not taken.
✗ Branch 31 not taken.
✓ Branch 32 taken 1 times.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
|
2 | EXPECT_THAT(actual, AnyOf(HasSubstr("copy"), HasSubstr("move"))); |
| 377 |
3/6✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
|
2 | std::cout << std::endl << actual << std::endl; |
| 378 | |||
| 379 |
2/4✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
|
2 | auto p2 = Verbose<Unmovable>{name}; |
| 380 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | CaptureStdout(); |
| 381 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | nrvo_output_parameter(p2); |
| 382 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | actual = GetCapturedStdout(); |
| 383 |
5/16✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✗ Branch 26 not taken.
✓ Branch 27 taken 1 times.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 40 not taken.
✗ Branch 41 not taken.
|
2 | EXPECT_THAT(p2.name(), Not(StrEq(name))); |
| 384 |
6/18✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 21 not taken.
✗ Branch 31 not taken.
✓ Branch 32 taken 1 times.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
|
2 | EXPECT_THAT(actual, AnyOf(HasSubstr("copy"), HasSubstr("move"))); |
| 385 |
3/6✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
|
2 | std::cout << std::endl << actual << std::endl; |
| 386 | 4 | } | |
| 387 | |||
| 388 | #endif // C++17 | ||
| 389 | |||
| 390 | #if __cplusplus >= 201402L // since C++14 | ||
| 391 | |||
| 392 | 8 | TEST(CopyElision, rvo_tuple_get) { | |
| 393 | // Good: use get to access tuple elements by reference | ||
| 394 | // without copying or moving. | ||
| 395 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | CaptureStdout(); |
| 396 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | auto result = rvo_tuple(); |
| 397 | 2 | auto& v1 = std::get<0>(result); | |
| 398 | 2 | auto& v2 = std::get<1>(result); | |
| 399 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | auto actual = GetCapturedStdout(); |
| 400 |
4/14✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
✗ Branch 20 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
|
2 | EXPECT_THAT(v1.name(), StrEq("first")); |
| 401 |
4/14✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
✗ Branch 20 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
|
2 | EXPECT_THAT(v2.name(), StrEq("second")); |
| 402 |
7/20✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
✓ Branch 24 taken 1 times.
✗ Branch 25 not taken.
✗ Branch 37 not taken.
✓ Branch 38 taken 1 times.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
|
2 | EXPECT_THAT(actual, Not(AnyOf(HasSubstr("copy"), HasSubstr("move")))); |
| 403 |
3/6✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
|
2 | std::cout << std::endl << actual << std::endl; |
| 404 | 4 | } | |
| 405 | |||
| 406 | #endif // C++14 | ||
| 407 | |||
| 408 | #if __cplusplus >= 201703L // since C++17 | ||
| 409 | |||
| 410 | 8 | TEST(CopyElision, rvo_tuple_structured_binding) { | |
| 411 | // Better: use structured binding to access tuple elements. | ||
| 412 | // Same efficiency, less verbose. | ||
| 413 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | CaptureStdout(); |
| 414 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
6 | auto [v1, v2] = rvo_tuple(); |
| 415 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | auto actual = GetCapturedStdout(); |
| 416 |
4/14✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
✗ Branch 20 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
|
2 | EXPECT_THAT(v1.name(), StrEq("first")); |
| 417 |
4/14✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
✗ Branch 20 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
|
2 | EXPECT_THAT(v2.name(), StrEq("second")); |
| 418 |
7/20✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
✓ Branch 24 taken 1 times.
✗ Branch 25 not taken.
✗ Branch 37 not taken.
✓ Branch 38 taken 1 times.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
|
2 | EXPECT_THAT(actual, Not(AnyOf(HasSubstr("copy"), HasSubstr("move")))); |
| 419 |
3/6✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
|
2 | std::cout << std::endl << actual << std::endl; |
| 420 |
1/4✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
|
6 | } |
| 421 | |||
| 422 | #endif // C++17 | ||
| 423 | |||
| 424 | #if __cplusplus >= 201402L // since C++14 | ||
| 425 | |||
| 426 | 8 | TEST(CopyElision, rvo_tuple_tie) { | |
| 427 | // Bad: use tie to access tuple elements. | ||
| 428 | // Constructor invoked for each local variable. | ||
| 429 | // Assignment operator invoked for each local variable. | ||
| 430 |
2/4✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
|
6 | auto v1 = Verbose<>{"one"}; |
| 431 |
2/4✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
|
6 | auto v2 = Verbose<>{"two"}; |
| 432 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | CaptureStdout(); |
| 433 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | std::tie(v1, v2) = rvo_tuple(); |
| 434 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | auto actual = GetCapturedStdout(); |
| 435 |
4/14✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
✗ Branch 19 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
|
2 | EXPECT_THAT(v1.name(), EndsWith("first")); |
| 436 |
4/14✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
✗ Branch 19 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
|
2 | EXPECT_THAT(v2.name(), EndsWith("second")); |
| 437 |
7/20✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
✓ Branch 24 taken 1 times.
✗ Branch 25 not taken.
✗ Branch 37 not taken.
✓ Branch 38 taken 1 times.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
|
2 | EXPECT_THAT( |
| 438 | actual, | ||
| 439 | Not( | ||
| 440 | AnyOf(HasSubstr("copy constructor"), | ||
| 441 | 2 | HasSubstr("move constructor")))); | |
| 442 |
4/14✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✗ Branch 17 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
|
2 | EXPECT_THAT(actual, HasSubstr("assignment")); |
| 443 |
3/6✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
|
2 | std::cout << std::endl << actual << std::endl; |
| 444 | 4 | } | |
| 445 | |||
| 446 | 8 | TEST(CopyElision, nrvo_tuple_get) { | |
| 447 | // Good: use get to access tuple elements by reference | ||
| 448 | // without copying or moving. | ||
| 449 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | CaptureStdout(); |
| 450 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | auto result = nrvo_tuple_good(); |
| 451 | 2 | auto& v1 = std::get<0>(result); | |
| 452 | 2 | auto& v2 = std::get<1>(result); | |
| 453 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | auto actual = GetCapturedStdout(); |
| 454 |
4/14✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
✗ Branch 20 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
|
2 | EXPECT_THAT(v1.name(), StrEq("first")); |
| 455 |
4/14✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
✗ Branch 20 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
|
2 | EXPECT_THAT(v2.name(), StrEq("second")); |
| 456 |
7/20✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
✓ Branch 24 taken 1 times.
✗ Branch 25 not taken.
✗ Branch 37 not taken.
✓ Branch 38 taken 1 times.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
|
2 | EXPECT_THAT(actual, Not(AnyOf(HasSubstr("copy"), HasSubstr("move")))); |
| 457 |
3/6✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
|
2 | std::cout << std::endl << actual << std::endl; |
| 458 | 4 | } | |
| 459 | |||
| 460 | #include "compat/lang17.hpp" | ||
| 461 | |||
| 462 | 8 | TEST(CopyElision, nrvo_tuple_macro) { | |
| 463 | // Good-ish: use macro to access tuple elements without copying or moving. | ||
| 464 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | CaptureStdout(); |
| 465 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | auto result = nrvo_tuple_good(); |
| 466 | 2 | STRUCTURED_BINDING_2(v1, v2, result); | |
| 467 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | auto actual = GetCapturedStdout(); |
| 468 |
4/14✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
✗ Branch 20 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
|
2 | EXPECT_THAT(v1.name(), StrEq("first")); |
| 469 |
4/14✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
✗ Branch 20 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
|
2 | EXPECT_THAT(v2.name(), StrEq("second")); |
| 470 |
7/20✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
✓ Branch 24 taken 1 times.
✗ Branch 25 not taken.
✗ Branch 37 not taken.
✓ Branch 38 taken 1 times.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
|
2 | EXPECT_THAT(actual, Not(AnyOf(HasSubstr("copy"), HasSubstr("move")))); |
| 471 |
3/6✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
|
2 | std::cout << std::endl << actual << std::endl; |
| 472 | 4 | } | |
| 473 | |||
| 474 | #endif // C++14 | ||
| 475 | |||
| 476 | #if __cplusplus >= 201703L // since C++17 | ||
| 477 | |||
| 478 | 8 | TEST(CopyElision, nrvo_tuple_structured_binding) { | |
| 479 | // Better: use structured binding to access tuple elements. | ||
| 480 | // Same efficiency, less verbose. | ||
| 481 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | CaptureStdout(); |
| 482 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
6 | auto [v1, v2] = nrvo_tuple_better(); |
| 483 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | auto actual = GetCapturedStdout(); |
| 484 |
4/14✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
✗ Branch 20 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
|
2 | EXPECT_THAT(v1.name(), StrEq("first")); |
| 485 |
4/14✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
✗ Branch 20 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 30 not taken.
✗ Branch 31 not taken.
✗ Branch 34 not taken.
✗ Branch 35 not taken.
|
2 | EXPECT_THAT(v2.name(), StrEq("second")); |
| 486 |
7/20✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
✓ Branch 24 taken 1 times.
✗ Branch 25 not taken.
✗ Branch 37 not taken.
✓ Branch 38 taken 1 times.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
|
2 | EXPECT_THAT(actual, Not(AnyOf(HasSubstr("copy"), HasSubstr("move")))); |
| 487 |
3/6✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
|
2 | std::cout << std::endl << actual << std::endl; |
| 488 |
1/4✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
|
6 | } |
| 489 | |||
| 490 | 8 | TEST(CopyElision, nrvo_tuple_tie) { | |
| 491 | // Bad: use tie to access tuple elements. | ||
| 492 | // Local variables must be constructed before call. | ||
| 493 | // Results are assigned to local variables. | ||
| 494 |
2/4✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
|
6 | auto v1 = Verbose{"one"}; |
| 495 |
2/4✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
|
6 | auto v2 = Verbose{"two"}; |
| 496 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | CaptureStdout(); |
| 497 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | std::tie(v1, v2) = nrvo_tuple_better(); |
| 498 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | auto actual = GetCapturedStdout(); |
| 499 |
4/14✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
✗ Branch 19 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
|
2 | EXPECT_THAT(v1.name(), EndsWith("first")); |
| 500 |
4/14✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
✗ Branch 19 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
|
2 | EXPECT_THAT(v2.name(), EndsWith("second")); |
| 501 |
7/20✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
✓ Branch 24 taken 1 times.
✗ Branch 25 not taken.
✗ Branch 37 not taken.
✓ Branch 38 taken 1 times.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
|
2 | EXPECT_THAT( |
| 502 | actual, | ||
| 503 | Not( | ||
| 504 | AnyOf(HasSubstr("copy constructor"), | ||
| 505 | 2 | HasSubstr("move constructor")))); | |
| 506 |
4/14✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✗ Branch 17 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
|
2 | EXPECT_THAT(actual, HasSubstr("assignment")); |
| 507 |
3/6✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
|
2 | std::cout << std::endl << actual << std::endl; |
| 508 | 4 | } | |
| 509 | |||
| 510 | #endif // C++17 | ||
| 511 | |||
| 512 | #if __cplusplus >= 201402L // since C++14 | ||
| 513 | |||
| 514 | 8 | TEST(CopyElision, nrvo_struct) { | |
| 515 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | CaptureStdout(); |
| 516 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | auto result = nrvo_struct(); |
| 517 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | auto actual = GetCapturedStdout(); |
| 518 |
4/14✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
✗ Branch 19 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
|
2 | EXPECT_THAT(result.first.name(), EndsWith("first")); |
| 519 |
4/14✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
✗ Branch 19 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
|
2 | EXPECT_THAT(result.second.name(), EndsWith("second")); |
| 520 |
7/20✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
✓ Branch 24 taken 1 times.
✗ Branch 25 not taken.
✗ Branch 37 not taken.
✓ Branch 38 taken 1 times.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
|
2 | EXPECT_THAT(actual, Not(AnyOf(HasSubstr("copy"), HasSubstr("move")))); |
| 521 |
3/6✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
|
2 | std::cout << std::endl << actual << std::endl; |
| 522 | 4 | } | |
| 523 | |||
| 524 | #endif // C++14 | ||
| 525 | |||
| 526 | #if __cplusplus >= 201703L // since C++17 | ||
| 527 | |||
| 528 | 8 | TEST(CopyElision, nrvo_struct_structured_binding) { | |
| 529 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | CaptureStdout(); |
| 530 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | auto [v1, v2] = nrvo_struct(); |
| 531 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | auto actual = GetCapturedStdout(); |
| 532 |
4/14✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
✗ Branch 19 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
|
2 | EXPECT_THAT(v1.name(), StrEq("first")); |
| 533 |
4/14✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
✗ Branch 19 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
|
2 | EXPECT_THAT(v2.name(), StrEq("second")); |
| 534 |
7/20✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
✓ Branch 24 taken 1 times.
✗ Branch 25 not taken.
✗ Branch 37 not taken.
✓ Branch 38 taken 1 times.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
|
2 | EXPECT_THAT(actual, Not(AnyOf(HasSubstr("copy"), HasSubstr("move")))); |
| 535 |
3/6✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
|
2 | std::cout << std::endl << actual << std::endl; |
| 536 | 4 | } | |
| 537 | |||
| 538 | #endif // C++17 | ||
| 539 | |||
| 540 | 8 | TEST(CopyElision, initialization) { | |
| 541 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | CaptureStdout(); |
| 542 |
2/4✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
|
6 | auto v1 = Verbose<>{"one"}; |
| 543 |
2/4✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
|
6 | auto v2 = Verbose<>{"two"}; |
| 544 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | auto actual = GetCapturedStdout(); |
| 545 |
7/20✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
✓ Branch 24 taken 1 times.
✗ Branch 25 not taken.
✗ Branch 37 not taken.
✓ Branch 38 taken 1 times.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
|
2 | EXPECT_THAT(actual, Not(AnyOf(HasSubstr("copy"), HasSubstr("move")))); |
| 546 |
3/6✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
|
2 | std::cout << std::endl << actual << std::endl; |
| 547 | 4 | } | |
| 548 | |||
| 549 | 8 | TEST(CopyElision, implicit_conversion) { | |
| 550 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | CaptureStdout(); |
| 551 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | auto v = implicit_conversion(); |
| 552 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | auto actual = GetCapturedStdout(); |
| 553 |
7/20✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
✓ Branch 24 taken 1 times.
✗ Branch 25 not taken.
✗ Branch 37 not taken.
✓ Branch 38 taken 1 times.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
|
2 | EXPECT_THAT(actual, Not(AnyOf(HasSubstr("copy"), HasSubstr("move")))); |
| 554 |
4/14✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
✗ Branch 19 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
|
2 | EXPECT_THAT(v.name(), StrEq("Converted to Verbose")); |
| 555 |
3/6✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
|
2 | std::cout << std::endl << actual << std::endl; |
| 556 | 4 | } | |
| 557 | |||
| 558 | 8 | TEST(CopyElision, explicit_conversion) { | |
| 559 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | CaptureStdout(); |
| 560 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | auto v = explicit_conversion(); |
| 561 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | auto actual = GetCapturedStdout(); |
| 562 |
7/20✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 22 not taken.
✓ Branch 24 taken 1 times.
✗ Branch 25 not taken.
✗ Branch 37 not taken.
✓ Branch 38 taken 1 times.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 47 not taken.
✗ Branch 48 not taken.
✗ Branch 51 not taken.
✗ Branch 52 not taken.
|
2 | EXPECT_THAT(actual, Not(AnyOf(HasSubstr("copy"), HasSubstr("move")))); |
| 563 |
4/14✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
✗ Branch 19 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
|
2 | EXPECT_THAT(v.name(), StrEq("Converted to Verbose")); |
| 564 |
3/6✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
|
2 | std::cout << std::endl << actual << std::endl; |
| 565 | 4 | } | |
| 566 | |||
| 567 | 8 | TEST(CopyElision, class_conversion) { | |
| 568 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | CaptureStdout(); |
| 569 | 2 | auto v = class_conversion(); | |
| 570 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | auto actual = GetCapturedStdout(); |
| 571 |
6/18✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 21 not taken.
✗ Branch 31 not taken.
✓ Branch 32 taken 1 times.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 41 not taken.
✗ Branch 42 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
|
2 | EXPECT_THAT(actual, AnyOf(HasSubstr("copy"), HasSubstr("move"))); |
| 572 |
5/16✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
✗ Branch 23 not taken.
✓ Branch 24 taken 1 times.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
|
2 | EXPECT_THAT(actual, Not(HasSubstr("assignment"))); |
| 573 |
4/14✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
✗ Branch 19 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
|
2 | EXPECT_THAT(v.name(), EndsWith("Derived")); |
| 574 |
3/6✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
|
2 | std::cout << std::endl << actual << std::endl; |
| 575 | 4 | } | |
| 576 |