Initial Course

This commit is contained in:
David Gil de Gómez Pérez
2026-08-11 17:40:36 +03:00
commit 9aed1d1d86
202 changed files with 3420 additions and 0 deletions
+8
View File
@@ -0,0 +1,8 @@
add_course_exercise(NAME auto_and_range_for MODULE 09_cpp11 STANDARD 11
SOURCES src/auto_and_range_for.cpp test/auto_and_range_for_test.cpp)
add_course_exercise(NAME smart_pointers MODULE 09_cpp11 STANDARD 11
SOURCES src/smart_pointers.cpp test/smart_pointers_test.cpp)
add_course_exercise(NAME move_semantics MODULE 09_cpp11 STANDARD 11
SOURCES src/move_semantics.cpp test/move_semantics_test.cpp)
add_course_exercise(NAME constexpr_nullptr MODULE 09_cpp11 STANDARD 11
SOURCES src/constexpr_nullptr.cpp test/constexpr_nullptr_test.cpp)
+17
View File
@@ -0,0 +1,17 @@
# Module 09: C++11 Foundations
## Learning Goals
- Use `auto`, range-based for, and uniform initialization
- Manage ownership with smart pointers
- Understand move semantics and rvalue references
- Apply `constexpr`, `nullptr`, and `enum class`
## Exercises
| Exercise | Standard Feature |
|----------|------------------|
| `auto_and_range_for` | Type deduction, range-for |
| `smart_pointers` | unique_ptr, shared_ptr |
| `move_semantics` | std::move, move constructors |
| `constexpr_nullptr` | constexpr functions, nullptr, enum class |
@@ -0,0 +1,12 @@
#pragma once
#include <string>
#include <vector>
namespace cpp11 {
[[nodiscard]] auto double_values(const std::vector<int>& input) -> std::vector<int>;
[[nodiscard]] auto join_with_auto(const std::vector<std::string>& parts) -> std::string;
[[nodiscard]] auto count_if_positive(const std::vector<int>& input) -> int;
} // namespace cpp11
@@ -0,0 +1,13 @@
#pragma once
#include <cstddef>
namespace cpp11 {
enum class Color { Red, Green, Blue };
[[nodiscard]] auto to_index(Color color) -> int;
[[nodiscard]] auto square(int value) -> int;
[[nodiscard]] auto find_null(int* ptr) -> int*;
} // namespace cpp11
@@ -0,0 +1,26 @@
#pragma once
#include <string>
#include <utility>
#include <vector>
namespace cpp11 {
class MovableBuffer {
public:
MovableBuffer() = default;
explicit MovableBuffer(std::vector<int> data);
MovableBuffer(const MovableBuffer&) = delete;
MovableBuffer(MovableBuffer&& other) noexcept;
auto operator=(MovableBuffer&& other) noexcept -> MovableBuffer&;
[[nodiscard]] auto size() const -> std::size_t;
[[nodiscard]] auto data() const -> const std::vector<int>&;
private:
std::vector<int> data_;
};
[[nodiscard]] auto consume(MovableBuffer buffer) -> std::size_t;
} // namespace cpp11
@@ -0,0 +1,12 @@
#pragma once
#include <memory>
#include <vector>
namespace cpp11 {
[[nodiscard]] auto make_counter(int start) -> std::unique_ptr<int>;
[[nodiscard]] auto shared_total(const std::vector<std::shared_ptr<int>>& values) -> int;
[[nodiscard]] auto clone_unique(const std::unique_ptr<int>& value) -> std::unique_ptr<int>;
} // namespace cpp11
@@ -0,0 +1,20 @@
#include "auto_and_range_for.hpp"
namespace cpp11 {
auto double_values(const std::vector<int>& input) -> std::vector<int> {
(void)input;
return {};
}
auto join_with_auto(const std::vector<std::string>& parts) -> std::string {
(void)parts;
return {};
}
auto count_if_positive(const std::vector<int>& input) -> int {
(void)input;
return 0;
}
} // namespace cpp11
@@ -0,0 +1,24 @@
#include "constexpr_nullptr.hpp"
namespace cpp11 {
auto to_index(Color color) -> int {
switch (color) {
case Color::Red: return 0;
case Color::Green: return 1;
case Color::Blue: return 2;
}
return -1;
}
auto square(int value) -> int {
(void)value;
return 0;
}
auto find_null(int* ptr) -> int* {
(void)ptr;
return nullptr;
}
} // namespace cpp11
+24
View File
@@ -0,0 +1,24 @@
#include "move_semantics.hpp"
namespace cpp11 {
MovableBuffer::MovableBuffer(std::vector<int> data) : data_(std::move(data)) {}
MovableBuffer::MovableBuffer(MovableBuffer&& other) noexcept : data_(std::move(other.data_)) {}
auto MovableBuffer::operator=(MovableBuffer&& other) noexcept -> MovableBuffer& {
if (this != &other) {
data_ = std::move(other.data_);
}
return *this;
}
auto MovableBuffer::size() const -> std::size_t { return data_.size(); }
auto MovableBuffer::data() const -> const std::vector<int>& { return data_; }
auto consume(MovableBuffer buffer) -> std::size_t {
(void)buffer;
return 0;
}
} // namespace cpp11
+20
View File
@@ -0,0 +1,20 @@
#include "smart_pointers.hpp"
namespace cpp11 {
auto make_counter(int start) -> std::unique_ptr<int> {
(void)start;
return nullptr;
}
auto shared_total(const std::vector<std::shared_ptr<int>>& values) -> int {
(void)values;
return 0;
}
auto clone_unique(const std::unique_ptr<int>& value) -> std::unique_ptr<int> {
(void)value;
return nullptr;
}
} // namespace cpp11
@@ -0,0 +1,14 @@
#include "auto_and_range_for.hpp"
#include <gtest/gtest.h>
TEST(AutoAndRangeFor, DoubleValues) {
EXPECT_EQ(cpp11::double_values({1, 2, 3}), (std::vector<int>{2, 4, 6}));
}
TEST(AutoAndRangeFor, JoinWithAuto) {
EXPECT_EQ(cpp11::join_with_auto({"C", "++", "11"}), "C++11");
}
TEST(AutoAndRangeFor, CountIfPositive) {
EXPECT_EQ(cpp11::count_if_positive({-1, 0, 2, 3}), 2);
}
@@ -0,0 +1,13 @@
#include "constexpr_nullptr.hpp"
#include <gtest/gtest.h>
TEST(ConstexprNullptr, EnumClass) {
EXPECT_EQ(cpp11::to_index(cpp11::Color::Green), 1);
EXPECT_EQ(cpp11::square(4), 16);
}
TEST(ConstexprNullptr, FindNull) {
int x = 1;
EXPECT_EQ(cpp11::find_null(&x), &x);
EXPECT_EQ(cpp11::find_null(nullptr), nullptr);
}
@@ -0,0 +1,9 @@
#include "move_semantics.hpp"
#include <gtest/gtest.h>
TEST(MoveSemantics, MoveTransfersOwnership) {
cpp11::MovableBuffer source{{1, 2, 3}};
const auto moved_size = cpp11::consume(std::move(source));
EXPECT_EQ(moved_size, 3U);
EXPECT_EQ(source.size(), 0U);
}
@@ -0,0 +1,22 @@
#include "smart_pointers.hpp"
#include <gtest/gtest.h>
TEST(SmartPointers, MakeCounter) {
auto counter = cpp11::make_counter(42);
ASSERT_NE(counter, nullptr);
EXPECT_EQ(*counter, 42);
}
TEST(SmartPointers, SharedTotal) {
std::vector<std::shared_ptr<int>> values;
values.push_back(std::make_shared<int>(1));
values.push_back(std::make_shared<int>(2));
EXPECT_EQ(cpp11::shared_total(values), 3);
}
TEST(SmartPointers, CloneUnique) {
auto original = cpp11::make_counter(7);
auto copy = cpp11::clone_unique(original);
ASSERT_NE(copy, nullptr);
EXPECT_EQ(*copy, 7);
}