Skip to content

Commit a6a460b

Browse files
authored
id 1772511655
id 1772511655
2 parents 87b9711 + 996a432 commit a6a460b

File tree

12 files changed

+941
-71
lines changed

12 files changed

+941
-71
lines changed

.clang-tidy

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Apply to ALL headers (empty = no restriction)
2+
HeaderFilterRegex: '.*'
3+
4+
# Treat warnings as errors (optional but recommended for CI)
5+
# WarningsAsErrors: '*'
6+
WarningsAsErrors: ''
7+
8+
Checks: >
9+
-*,
10+
clang-diagnostic-*,
11+
modernize-*,
12+
-modernize-use-trailing-return-type,
13+
-modernize-use-auto,
14+
cppcoreguidelines-*,
15+
-cppcoreguidelines-owning-memory,
16+
-cppcoreguidelines-pro-type-vararg,
17+
-cppcoreguidelines-avoid-magic-numbers,
18+
bugprone-*,
19+
performance-*,
20+
readability-*,
21+
-readability-magic-numbers,
22+
-readability-identifier-length,
23+
misc-*,
24+
-misc-unused-parameters
25+
26+
CheckOptions:
27+
- key: readability-identifier-naming.NamespaceCase
28+
value: lower_case
29+
30+
- key: readability-identifier-naming.ClassCase
31+
value: CamelCase
32+
33+
- key: readability-identifier-naming.StructCase
34+
value: CamelCase
35+
36+
- key: readability-identifier-naming.FunctionCase
37+
value: lower_case
38+
39+
- key: readability-identifier-naming.VariableCase
40+
value: lower_case
41+
42+
- key: readability-identifier-naming.MemberCase
43+
value: lower_case
44+
45+
- key: modernize-use-nullptr.NullMacros
46+
value: 'NULL'

.github/workflows/cpp-build-test-coverage.yml

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ jobs:
5757
--inline-suppr \
5858
--error-exitcode=1 \
5959
./src ./include
60-
60+
6161
# -------------------------------------------------------
6262
# Step 3: Configure and build the project
6363
# -------------------------------------------------------
@@ -97,3 +97,22 @@ jobs:
9797
cd build
9898
echo "## Test Coverage Summary" >> $GITHUB_STEP_SUMMARY
9999
lcov --summary coverageFiltered.info >> $GITHUB_STEP_SUMMARY
100+
101+
# -------------------------------------------------------
102+
# Step 7: Run Clang-Tidy (experimenting , not exit)
103+
# - Modern C++ static analysis
104+
# - Enforces best practices
105+
# - Add `--warnings-as-errors=*` to exit code 1
106+
# -------------------------------------------------------
107+
- name: Run clang-tidy
108+
# run: |
109+
# echo "Running clang-tidy..."
110+
# clang-tidy \
111+
# -checks='clang-analyzer-*,modernize-*,performance-*,readability-*' \
112+
# -p build \
113+
# $(find ./src -name '*.cpp')
114+
run: |
115+
echo "Running clang-tidy using .clang-tidy options"
116+
clang-tidy \
117+
-p build \
118+
-header-filter='^src/.*' $(find src -name "*.cpp")

CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ set(PROJECT_NAME_TEST ${PROJECT_NAME}_unit_test) # name for the unit-test execut
2727
# Require at least C++17 for GoogleTest and modern C++ features
2828
set(CMAKE_CXX_STANDARD 20)
2929
set(CMAKE_CXX_STANDARD_REQUIRED ON)
30+
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # Enable output of compile commands for clang-tidy
3031

3132
# Optionally enforce warnings (good for learning/debugging)
3233
add_compile_options(-Wall -Wextra -Wpedantic)
@@ -123,6 +124,8 @@ set(APP_SOURCES
123124
"src/patterns/creational/Builder.cpp"
124125
"src/patterns/creational/Prototype.cpp"
125126
"src/core/datatypes/class/Relationship.cpp"
127+
"src/core/datatypes/class/VirtualBase.cpp"
128+
"src/core/datatypes/class/Binding.cpp"
126129
## Exceptions
127130
"src/core/exception/BasicHandle.cpp"
128131
"src/core/exception/ThrowNoexcept.cpp"
@@ -131,6 +134,8 @@ set(APP_SOURCES
131134
"src/core/filehandle/StringStream.cpp"
132135
"src/core/filehandle/FileIO.cpp"
133136
"src/core/filehandle/Directory.cpp"
137+
"src/core/filehandle/OutputFormatting.cpp"
138+
"src/core/filehandle/BinaryFileHandling.cpp"
134139
## Container
135140
"src/core/datatypes/container/sequence/Array.cpp"
136141
"src/core/datatypes/container/sequence/Vector.cpp"

Dockerfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ RUN \
1414
apt-get install -y gcc g++ && \
1515
# install cppcheck
1616
apt-get install -y cppcheck && \
17+
# install clang tidy
18+
apt-get install -y clang-tidy && \
1719
# install lcov
1820
apt-get install -y lcov
1921

README.md

Lines changed: 79 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
## 1. OVERVIEW
1+
## 1. Overview
22
**Project Structure**
33
```
44
includes/ → Header files (.h, .hpp)
55
src/ → Source files (.cpp)
66
tests/ → GoogleTest test cases
77
```
8-
## 2. DEPENDENCIES
8+
## 2. Dependencies
99
Make sure the following tools are installed before building the project:
1010
- **g++ / gcc**
1111
- **CMake**
@@ -14,68 +14,92 @@ Make sure the following tools are installed before building the project:
1414
- **cppcheck** (for static analysis)
1515
- **Optional:** Install `clang-format` to format C++ code.
1616

17-
Linux
17+
**Linux**
1818
```bash
1919
sudo apt install clang-format
2020
find . -regex '.*\.\(cpp\|h\|hpp\)' -exec clang-format -i {} \;
2121
```
22-
Windows
22+
**Windows**
2323
```bash
2424
# Install clang-format via Chocolatey
2525
choco install clang-format
2626

2727
# Apply clang-format recursively to .cpp, .h, .hpp files
2828
Get-ChildItem -Recurse -Include *.cpp, *.h, *.hpp | ForEach-Object { clang-format -i $_.FullName }
2929
```
30-
## 3. SETUP
31-
* Setup the Local Test Environment
32-
* 1.Using your own Ubuntu system
33-
* Install `gcc`, `cmake`, `git`, and `pthread` (Skip this step if you already install)
34-
```
35-
$ sudo apt-get update
36-
$ sudo apt-get install g++
37-
$ sudo apt-get install lcov
38-
$ sudo apt-get install cmake
39-
$ sudo apt-get install git
40-
$ sudo apt-get install cppcheck
41-
```
42-
* Build the application and the tests
43-
```
44-
$ cd build
45-
$ cmake ..
46-
$ cmake --build .
47-
```
48-
* Run the application and the test
49-
```
50-
$ ./cpp_lab_project
51-
$ ./cpp_lab_project_test
52-
```
53-
* (Optional) Run static analysis
54-
```
55-
$ sudo apt-get install cppcheck
56-
$ cppcheck "folder" / "file"
57-
```
58-
* 2.Using **Docker**
59-
* Build the Docker image
60-
```
61-
docker build --tag sample-ci-cpp .
62-
```
63-
* Run an interactive container
64-
```
65-
docker run -it sample-ci-cpp:latest /bin/bash
66-
```
67-
* Inspect the environment
68-
```
69-
printenv
70-
```
71-
* *Notes:*
72-
* Use the -t or --tag flag to set the name of the image to be created. (the full name is actually sample-ci-cpp:latest, since latest is the default tag)
73-
* Opening an interactive shell inside your Docker container to explore, test, or debug the environment built from your image.
74-
* docker run to start a new container.
75-
* -it → run it interactively:
76-
* -i = keep STDIN open (so you can type commands)
77-
* -t = allocate a terminal (TTY)
78-
* sample-ci-cpp:latest → the image you built earlier.
79-
* /bin/bash → the command to execute inside the container (opens a Bash shell).
30+
## 3. Setup
31+
### 3.1. Setup the Local Test Environment
32+
- **Ubuntu system**
33+
* Install `gcc`, `cmake`, `git`, and `pthread` (Skip this step if you already install)
34+
```
35+
$ sudo apt-get update
36+
$ sudo apt-get install g++
37+
$ sudo apt-get install lcov
38+
$ sudo apt-get install cmake
39+
$ sudo apt-get install git
40+
$ sudo apt-get install cppcheck
41+
```
42+
* Build the application and the tests
43+
```
44+
$ cd build
45+
$ cmake ..
46+
$ cmake --build .
47+
```
48+
* Run the application and the test
49+
```
50+
$ ./cpp_lab_project
51+
$ ./cpp_lab_project_test
52+
```
53+
* (Optional) Run static analysis - cppcheck
54+
```
55+
$ sudo apt-get install cppcheck
56+
$ cppcheck "folder" / "file"
57+
```
58+
* (Optional) Run static analysis - clang-tidy
59+
```
60+
$ sudo apt-get install -y clang-tidy
61+
$ clang-tidy -p build -header-filter='^src/.*' $(find src -name "*.cpp")
62+
```
63+
- **Docker**
64+
* Update `Dockerfile`
65+
* Build the Docker image
66+
```
67+
$ cd build
68+
$ docker build --tag cpp-lab .
69+
```
70+
* Run an interactive container
71+
```
72+
$ docker run -it cpp-lab:latest /bin/bash
73+
```
74+
* Inspect the environment
75+
```
76+
$ printenv
77+
```
78+
* *Notes:*
79+
* Use the `-t` or `--tag` flag to set the name of the image to be created. (the full name is actually `cpp-lab:latest`, since latest is the default tag)
80+
* Opening an interactive shell inside your Docker container to explore, test, or debug the environment built from your image.
81+
* docker run to start a new container.
82+
* `-it`: run it interactively:
83+
* `-i`: keep STDIN open (so you can type commands)
84+
* `-t`: allocate a terminal (TTY)
85+
* `cpp-lab:latest`: the image you built earlier.
86+
* `/bin/bash`: the command to execute inside the container (opens a Bash shell).
8087
81-
## 4. DOCUMENTATIONS
88+
## 5. Update Docker Image
89+
```bash
90+
# Navigate to the project that contain your Dockerfile
91+
cd cpp-lab
92+
93+
# Build the project by running the following command, swapping out DOCKER_USERNAME with your username.
94+
docker build -t DOCKER_USERNAME/cpp-lab .
95+
96+
# Verify the image exists locally
97+
docker image ls
98+
99+
# To push the image
100+
docker push DOCKER_USERNAME/cpp-lab
101+
```
102+
103+
## 6. TROUBLESHOOTING
104+
1. `push access denied, repository does not exist or may require authorization: server message: insufficient_scope: authorization failed`
105+
=> docker login / Docker Desktop login

src/core/datatypes/TypeConVersions.cpp

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// cppcheck-suppress-file [unreadVariable]
12
#include <iostream>
23
using namespace std;
34

@@ -12,6 +13,11 @@ class Derived : public Base {
1213
void show() override { cout << "Derived class\n"; }
1314
};
1415

16+
class DerivedX : public Base {
17+
public:
18+
void show() override { cout << "DerivedX class\n"; }
19+
};
20+
1521
void implicitConversion() {
1622
cout << "\n--- Implicit Type Conversion ---\n";
1723
// *1. Numeric promotion (safe, no data loss)
@@ -39,48 +45,59 @@ void explicitConversion() {
3945

4046
double pi = 3.14159;
4147

42-
// *1. C-style cast
48+
// *1. C-style cast - not safe
4349
int pi_c = (int)pi;
4450
cout << "C-style cast: " << pi_c << "\n";
4551

46-
// *2. static_cast - compile-time type checking
52+
// **2. static_cast - type-safe relationship + compile-time type checking**
4753
int pi_static = static_cast<int>(pi);
4854
cout << "static_cast: " << pi_static << "\n";
4955

50-
// object -> object
56+
// object -> object
5157
Derived derived{};
52-
[[maybe_unused]] Base baseObj = static_cast<Derived>(derived);
53-
// object -> reference
58+
Base baseObj = static_cast<Derived>(derived);
59+
// DerivedX derivedx =static_cast<Derived>(derived); // ERROR
60+
61+
// object -> reference
5462
const Base& baseRef = static_cast<Derived&>(derived);
5563
// object -> ptr
56-
[[maybe_unused]] const Base* base_ptr = static_cast<Derived*>(&derived);
64+
const Base* base_ptr = static_cast<Derived*>(&derived);
5765

58-
// *3. const_cast: const_cast adds or removes the const qualifier
66+
// **3. const_cast: const_cast adds or removes the const qualifier**
5967
const double c_pi = 2.71828;
6068
const double* pConst = &c_pi;
6169
const double* pNonConst = const_cast<double*>(pConst); // remove const
6270
cout << "const_cast: " << *pNonConst << " (removed const)\n";
6371

64-
// *4. reinterpret_cast: reinterpret memory (unsafe)
72+
// **4. reinterpret_cast: reinterpret memory (unsafe)**
73+
// It is used to convert a pointer of some data type into a pointer of another data type,
74+
// even if the data types before and after conversion are different. (#static,dynamic)
75+
// It does not check if the pointer type and data pointed by the pointer is same or not.
6576
const void* pVoid = reinterpret_cast<const void*>(&pi);
6677
cout << "reinterpret_cast: address of pi = " << pVoid << "\n";
6778

68-
// ** Use case: Memory-Mapped I/O **
69-
// C
79+
// ******************** Use case: Memory-Mapped I/O ******************************
80+
// C ===============================================
7081
// #define REG_ADDR 0x000fff01
7182
// volatile uint8_t* reg = reinterpret_cast<volatile uint8_t*>(REG_ADDR);
7283
// *reg = 0xF;
7384
// *reg = 0x1;
7485

75-
// C++
86+
// C++ ===============================================
7687
// #include <cstdint>
7788
// constexpr std::uintptr_t REG_ADDR = 0x000fff02;
7889
// auto* const reg = reinterpret_cast<volatile uint8_t*>(REG_ADDR);
7990
// *reg = 0xF;
80-
8191
// *reg = 0x1;
92+
// ********************************************************************************
93+
94+
// **5. dynamic_cast: safe cast between related classes - type-safe relationship + run-time type checking**
95+
// RTTI (RunTime Type Information) check
96+
// #include <typeinfor>
97+
// if(typeid(*basePtr) == typeid(Derived)){
98+
// Derived* derivedPtr = dynamic_cast<Derived*>(basePtr)
99+
// }
82100

83-
// *5. dynamic_cast: safe cast between related classes (runtime checked)
84101
Base* basePtr = new Derived();
85102
const Derived* derivedPtr = dynamic_cast<Derived*>(basePtr);
86103
if (derivedPtr)
@@ -102,11 +119,11 @@ void typeAliases() {
102119

103120
// *1. using - preferred
104121
using MyDouble = double;
105-
[[maybe_unused]] const MyDouble a = 3.14;
122+
const MyDouble a = 3.14;
106123

107124
// *2. typedef - old style
108125
typedef double OldDouble;
109-
[[maybe_unused]] OldDouble b = 2.718;
126+
OldDouble b = 2.718;
110127

111128
// *3. Function pointer alias
112129
using FuncType = int (*)(double, char);

0 commit comments

Comments
 (0)