You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
100 lines
3.1 KiB
100 lines
3.1 KiB
#include <catch2/catch_test_macros.hpp>
|
|
#include <fmt/core.h>
|
|
#include <string>
|
|
#include <iostream>
|
|
#include <vector>
|
|
#include <cstdlib>
|
|
|
|
using namespace fmt;
|
|
|
|
// Some heavy object
|
|
struct A {
|
|
A() = default;
|
|
|
|
A(int val) : val(val) {
|
|
std::cout << "called constructor with: " << val << std::endl;
|
|
}
|
|
|
|
A(A const& other) {
|
|
std::cout << "calling copy(A const& other): " << val << std::endl;;
|
|
}
|
|
A(A&& other) {
|
|
std::cout << "calling move(A&& other): " << val << std::endl;;
|
|
}
|
|
|
|
A& operator=(A&& other) {
|
|
std::cout << "calling move(A&& other)=: " << val << std::endl;;
|
|
return *this;
|
|
}
|
|
|
|
A& operator=(A const& other) {
|
|
std::cout << "calling copy(A const& other)=: " << val << std::endl;;
|
|
return *this;
|
|
}
|
|
|
|
~A() = default;
|
|
|
|
int val{};
|
|
};
|
|
|
|
|
|
TEST_CASE("emplace move tests", "[emplace]") {
|
|
A a{10};
|
|
std::vector<A> test;
|
|
test.reserve(10); // to prevent vector resizing and creating new objects on the way
|
|
std::cout << "===== Emplacing Start =====\n";
|
|
// pass by l-value and will call copy constructor since it'll match
|
|
// A(A const&)
|
|
std::cout << "== 1. Emplace: Calling copy constructor \n";
|
|
test.emplace_back(a);
|
|
|
|
// pass by r-value and will call move constructor since it'll match
|
|
// A(A&&)
|
|
std::cout << "== 2. Emplace: Calling move constructor \n";
|
|
test.emplace_back(std::move(a));
|
|
|
|
std::cout << "== 3. Emplace: Calling move constructor without direct constructor\n";
|
|
test.emplace_back(100);
|
|
|
|
// pass by pr-value (pure r-value which is those value that has not come to an existance yet)
|
|
// and will call move constructor since it'll match A(A&&).
|
|
// "copy-elision" could be applied here but I don't know why compilers
|
|
// refused to do it. Maybe how vectors are implemented and you need
|
|
// to put the value in a slot so the compiler had to call the move constructor
|
|
std::cout << "== 4. Emplace: Calling move constructor\n";
|
|
test.emplace_back(A{});
|
|
}
|
|
|
|
TEST_CASE("pushback move tests", "[push_back]") {
|
|
std::cout << "\n\n!!!!!!!!!! PUSH BACK alternative !!!!!!!!!!\n";
|
|
|
|
A a{20};
|
|
std::vector<A> test;
|
|
test.reserve(10); // to prevent vector resizing and creating new objects on the way
|
|
std::cout << "===== Push Back Start =====\n";
|
|
// pass by l-value and will call copy constructor since it'll match
|
|
// A(A const&)
|
|
std::cout << "== 1. Push Back: Calling copy constructor \n";
|
|
test.push_back(a);
|
|
|
|
// pass by r-value and will call move constructor since it'll match
|
|
// A(A&&)
|
|
std::cout << "== 2. Push Back: Calling move constructor \n";
|
|
test.push_back(std::move(a));
|
|
|
|
std::cout << "== 3. Push Back: Calling move constructor without direct constructor\n";
|
|
test.push_back(200);
|
|
|
|
// pass by pr-value (pure r-value which is those value that has not come to an existance yet)
|
|
// and will call move constructor since it'll match A(A&&).
|
|
// "copy-elision" could be applied here but I don't know why compilers
|
|
// refused to do it. Maybe how vectors are implemented and you need
|
|
// to put the value in a slot so the compiler had to call the move constructor
|
|
std::cout << "== 4. Push Back: Calling move constructor\n";
|
|
test.push_back(A{});
|
|
}
|
|
|
|
|
|
TEST_CASE("proof you don't need emplace or std::move", "[proof]") {
|
|
|
|
}
|
|
|