A repository where I'll put experiments learning, proving or disproving things about C++. These experiments will feature measurements, use Tracy to show behavior, and generally have the goal of simplifying normal C++ usage.
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.

101 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]") {
}