Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,18 @@ cpp_lab_add_executable(en_10_templates en/10_templates/template_repository.cpp)
cpp_lab_add_executable(en_11_low_level en/11_low_level_cpp/bytes_alignment_flags.cpp)
cpp_lab_add_executable(en_12_concurrency en/12_concurrency/thread_safe_counter.cpp)
cpp_lab_add_executable(en_13_patterns en/13_patterns_architecture/strategy_pattern.cpp)
cpp_lab_add_executable(en_14_core_language en/14_core_language_details/scope_enum_static.cpp)
cpp_lab_add_executable(en_15_strings_views en/15_strings_views/string_string_view.cpp)
cpp_lab_add_executable(en_16_containers en/16_containers_iterators/map_set_iterator.cpp)
cpp_lab_add_executable(en_17_lambdas en/17_lambdas_algorithms/lambda_algorithm_pipeline.cpp)
cpp_lab_add_executable(en_18_constexpr en/18_compile_time_constexpr/constexpr_lookup.cpp)
cpp_lab_add_executable(en_19_variant_tuple en/19_variant_tuple_enum/variant_tuple_enum.cpp)
cpp_lab_add_executable(en_20_operator_overloading en/20_operator_overloading/value_type_operator.cpp)
cpp_lab_add_executable(en_21_namespaces en/21_namespaces_headers/namespace_api_design.cpp)
cpp_lab_add_executable(en_22_casts en/22_casts_type_safety/casts_type_safety.cpp)
cpp_lab_add_executable(en_23_testing en/23_testing_practices/simple_test_harness.cpp)
cpp_lab_add_executable(en_24_filesystem_chrono en/24_filesystem_chrono/filesystem_chrono.cpp)
cpp_lab_add_executable(en_25_atomics en/25_atomics_intro/atomic_counter.cpp)

cpp_lab_add_executable(tr_00_merhaba tr/00_toolchain/hello_modern_cpp.cpp)
cpp_lab_add_executable(tr_01_tipler tr/01_basics/types_and_initialization.cpp)
Expand All @@ -73,6 +85,18 @@ cpp_lab_add_executable(tr_10_templates tr/10_templates/template_repository.cpp)
cpp_lab_add_executable(tr_11_low_level tr/11_low_level_cpp/bytes_alignment_flags.cpp)
cpp_lab_add_executable(tr_12_concurrency tr/12_concurrency/thread_safe_counter.cpp)
cpp_lab_add_executable(tr_13_patterns tr/13_patterns_architecture/strategy_pattern.cpp)
cpp_lab_add_executable(tr_14_core_language tr/14_core_language_details/scope_enum_static.cpp)
cpp_lab_add_executable(tr_15_strings_views tr/15_strings_views/string_string_view.cpp)
cpp_lab_add_executable(tr_16_containers tr/16_containers_iterators/map_set_iterator.cpp)
cpp_lab_add_executable(tr_17_lambdas tr/17_lambdas_algorithms/lambda_algorithm_pipeline.cpp)
cpp_lab_add_executable(tr_18_constexpr tr/18_compile_time_constexpr/constexpr_lookup.cpp)
cpp_lab_add_executable(tr_19_variant_tuple tr/19_variant_tuple_enum/variant_tuple_enum.cpp)
cpp_lab_add_executable(tr_20_operator_overloading tr/20_operator_overloading/value_type_operator.cpp)
cpp_lab_add_executable(tr_21_namespaces tr/21_namespaces_headers/namespace_api_design.cpp)
cpp_lab_add_executable(tr_22_casts tr/22_casts_type_safety/casts_type_safety.cpp)
cpp_lab_add_executable(tr_23_testing tr/23_testing_practices/simple_test_harness.cpp)
cpp_lab_add_executable(tr_24_filesystem_chrono tr/24_filesystem_chrono/filesystem_chrono.cpp)
cpp_lab_add_executable(tr_25_atomics tr/25_atomics_intro/atomic_counter.cpp)

add_subdirectory(en/projects/bank_account_oop)
add_subdirectory(tr/projects/bank_account_oop)
15 changes: 14 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ industry-friendly.
- English and Turkish learning paths and reference indexes.
- Examples for toolchain, types, references, OOP, RAII, smart pointers, move
semantics, STL, templates, error handling, file I/O, low-level C++, threading,
and architecture patterns.
lambdas, compile-time programming, strings/views, casts, testing, filesystem,
chrono, atomics, and architecture patterns.
- A modular OOP bank account project with library, demo, and tests.

## How To Build
Expand Down Expand Up @@ -80,6 +81,18 @@ ctest --test-dir build --output-on-failure
- `11_low_level_cpp`: bytes, alignment, flags, and systems mental model.
- `12_concurrency`: threads, mutexes, and safe shared state.
- `13_patterns_architecture`: small design patterns without overengineering.
- `14_core_language_details`: scope, `enum class`, `static`, and state control.
- `15_strings_views`: `std::string`, `std::string_view`, and text lifetime.
- `16_containers_iterators`: map, set, iterator usage, and container choice.
- `17_lambdas_algorithms`: captures, predicates, transforms, and algorithm use.
- `18_compile_time_constexpr`: `constexpr`, `static_assert`, compile-time data.
- `19_variant_tuple_enum`: `std::variant`, `std::tuple`, and alternative data.
- `20_operator_overloading`: value-type operators without surprising behavior.
- `21_namespaces_headers`: API boundaries, namespaces, and header discipline.
- `22_casts_type_safety`: explicit casts and safer downcasting.
- `23_testing_practices`: simple deterministic tests and failure behavior.
- `24_filesystem_chrono`: portable paths and type-safe time measurement.
- `25_atomics_intro`: atomic counters and shared state basics.

## Maintenance Rule

Expand Down
31 changes: 31 additions & 0 deletions docs/coverage-map.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Coverage Map

This repository is meant to be a practical C++ handbook, not a copy of the
entire language standard. The default coverage is complete for foundation and
intermediate review.

## Covered For Daily Work

- build tools, CMake, and CI
- basic types, initialization, scope, `enum class`, and `static`
- functions, references, const-correctness, and API intent
- classes, encapsulation, invariants, polymorphism, virtual destructors, object
slicing, and operator overloading
- RAII, smart pointers, ownership, move semantics, Rule of 0, and Rule of 5
- STL containers, iterators, algorithms, lambdas, strings, and string views
- templates, `constexpr`, `std::optional`, `std::variant`, and `std::tuple`
- file I/O, filesystem, chrono, casts, low-level bytes, flags, and alignment
- threads, mutexes, atomics, testing practices, and simple architecture patterns

## Not The Main Target

These topics are useful but should not block the handbook from being practical:

- advanced template metaprogramming
- custom allocators
- lock-free data structures
- coroutine frameworks
- modules in production build systems
- compiler-specific embedded register maps

Add those only when there is a concrete learning or work need.
16 changes: 16 additions & 0 deletions docs/repo-roadmap.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ the mental model and one focused example that compiles in CI.
- STL containers and algorithms.
- Templates and generic code.
- Error handling, file I/O, low-level C++, and concurrency.
- Lambdas, strings/views, associative containers, constexpr, variant/tuple,
casts, operator overloading, testing, filesystem/chrono, and atomics.

## Project Layer

Expand All @@ -34,3 +36,17 @@ scripts.
- The topic is linked from `LEARNING_PATH.md`.
- The code teaches a real concept, not only syntax.
- Naming and formatting match the rest of the repository.

## Advanced Topics Kept As Notes

Some modern C++ features are intentionally not required by the default build
because the repository targets a C++17 production baseline:

- C++20 concepts
- C++20 ranges
- C++20 coroutines
- C++20 modules
- C++23 library additions

These can be added later as optional notes or separate examples without making
the main handbook harder to build in conservative toolchains.
23 changes: 23 additions & 0 deletions en/14_core_language_details/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Core Language Details

Small language rules shape large C++ programs. Scopes, `enum class`, `static`,
`const`, and namespaces help keep names and state controlled.

## Mental Model

- Scope decides where a name is visible.
- `enum class` avoids unscoped integer-like enum pollution.
- `static` local variables keep state between calls.
- `static` class members belong to the class, not one object.
- Prefer explicit ownership and explicit state over hidden globals.

## Common Mistakes

- Using unscoped `enum` values that collide with other names.
- Hiding state in globals when a class or function parameter would be clearer.
- Confusing `const` object state with compile-time constants.

## Example

- `scope_enum_static.cpp`: shows controlled names, scoped enum values, and class
level state.
53 changes: 53 additions & 0 deletions en/14_core_language_details/scope_enum_static.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#include <iostream>
#include <string>

enum class LogLevel {
info,
warning,
error,
};

std::string toString(const LogLevel level) {
switch (level) {
case LogLevel::info:
return "info";
case LogLevel::warning:
return "warning";
case LogLevel::error:
return "error";
}

return "unknown";
}

class Logger {
public:
explicit Logger(LogLevel minimumLevel) : minimumLevel_{minimumLevel} {
++createdCount_;
}

void print(LogLevel level, const std::string& message) const {
if (static_cast<int>(level) >= static_cast<int>(minimumLevel_)) {
std::cout << "[" << toString(level) << "] " << message << '\n';
}
}

static int createdCount() noexcept {
return createdCount_;
}

private:
LogLevel minimumLevel_;
static int createdCount_;
};

int Logger::createdCount_ = 0;

int main() {
Logger logger{LogLevel::warning};
logger.print(LogLevel::info, "hidden");
logger.print(LogLevel::error, "shown");

std::cout << "logger count: " << Logger::createdCount() << '\n';
return 0;
}
22 changes: 22 additions & 0 deletions en/15_strings_views/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Strings And Views

`std::string` owns text. `std::string_view` observes text. Knowing the
difference prevents needless copies and dangling views.

## Mental Model

- `std::string` stores and owns characters.
- `std::string_view` points at existing characters and does not own them.
- Use `std::string_view` for read-only function parameters when the function
does not store the view.
- Never return a `string_view` to a local `std::string`.

## Common Mistakes

- Storing a `string_view` after the original string has been destroyed.
- Using C-style string functions when `std::string` is enough.
- Passing large strings by value when no copy is needed.

## Example

- `string_string_view.cpp`: trims and checks text without copying it.
29 changes: 29 additions & 0 deletions en/15_strings_views/string_string_view.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#include <iostream>
#include <string>
#include <string_view>

std::string_view trimSpaces(std::string_view text) noexcept {
while (!text.empty() && text.front() == ' ') {
text.remove_prefix(1);
}

while (!text.empty() && text.back() == ' ') {
text.remove_suffix(1);
}

return text;
}

bool startsWith(std::string_view text, std::string_view prefix) noexcept {
return text.size() >= prefix.size() && text.substr(0, prefix.size()) == prefix;
}

int main() {
const std::string command{" upload:file.txt "};
const std::string_view trimmed = trimSpaces(command);

std::cout << "trimmed: " << trimmed << '\n';
std::cout << "is upload: " << std::boolalpha << startsWith(trimmed, "upload:") << '\n';

return 0;
}
23 changes: 23 additions & 0 deletions en/16_containers_iterators/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Containers And Iterators

STL containers solve different storage and lookup problems. Iterators are the
common access model that lets algorithms work with many containers.

## Mental Model

- `std::vector` is the default sequence container.
- `std::map` keeps keys ordered.
- `std::unordered_map` optimizes average lookup by hash.
- `std::set` stores unique sorted values.
- Iterators point into containers; invalidation rules matter.

## Common Mistakes

- Choosing `map` when unordered lookup would be enough.
- Erasing from a container while using an invalidated iterator.
- Using a container without thinking about lookup and iteration needs.

## Example

- `map_set_iterator.cpp`: builds a frequency table and extracts sorted unique
keys.
31 changes: 31 additions & 0 deletions en/16_containers_iterators/map_set_iterator.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include <iostream>
#include <map>
#include <set>
#include <string>
#include <vector>

int main() {
const std::vector<std::string> tags{
"cpp",
"systems",
"cpp",
"oop",
"systems",
"templates",
};

std::map<std::string, int> frequencies;
std::set<std::string> uniqueTags;

for (const auto& tag : tags) {
++frequencies[tag];
uniqueTags.insert(tag);
}

for (auto it = frequencies.begin(); it != frequencies.end(); ++it) {
std::cout << it->first << " -> " << it->second << '\n';
}

std::cout << "unique tag count: " << uniqueTags.size() << '\n';
return 0;
}
23 changes: 23 additions & 0 deletions en/17_lambdas_algorithms/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Lambdas And Algorithms

Lambdas let behavior stay close to the algorithm that uses it. They are most
useful when paired with standard algorithms.

## Mental Model

- `[]` is the capture list.
- `[value]` captures by value.
- `[&value]` captures by reference.
- Prefer algorithms when they express intent more clearly than manual loops.
- Keep lambdas short and named with variables when they become important.

## Common Mistakes

- Capturing references that outlive the referenced object.
- Writing a long lambda that should be a named function.
- Using `for_each` when a simple range-for loop is clearer.

## Example

- `lambda_algorithm_pipeline.cpp`: filters, transforms, and sums values with
lambdas and algorithms.
40 changes: 40 additions & 0 deletions en/17_lambdas_algorithms/lambda_algorithm_pipeline.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#include <algorithm>
#include <iostream>
#include <numeric>
#include <string>
#include <vector>

struct Order {
std::string customer;
double total;
};

int main() {
std::vector<Order> orders{
{"Ada", 120.0},
{"Bjarne", 80.0},
{"Grace", 210.0},
};

const double minimum = 100.0;
const auto isLargeOrder = [minimum](const Order& order) {
return order.total >= minimum;
};

std::vector<double> largeTotals;
for (const auto& order : orders) {
if (isLargeOrder(order)) {
largeTotals.push_back(order.total);
}
}

std::transform(largeTotals.begin(), largeTotals.end(), largeTotals.begin(), [](double total) {
return total * 1.20;
});

const double sum = std::accumulate(largeTotals.begin(), largeTotals.end(), 0.0);

std::cout << "large order count: " << largeTotals.size() << '\n';
std::cout << "taxed total: " << sum << '\n';
return 0;
}
Loading
Loading