A modular, dependency-free C++17 Library Management System designed as a software engineering portfolio project.
The system demonstrates practical use of data structures, encapsulation, validation, persistence, sorting/searching algorithms, state-based undo/redo, automated testing, CMake, and GitHub Actions CI.
- Add and remove books
- Unique book-code validation
- Search by code, title, or author
- Case-insensitive ASCII search
- Borrow and return workflows
- FIFO waiting lists
- Duplicate waiting-request protection
- Automatic assignment to the next waiting borrower
- Stable sorting by code and publication year
- Statistics dashboard
- Activity history
- Reliable state-based undo/redo
- CSV persistence
- CSV quoting/escaping support
- Strict CSV validation
- Dependency-free unit tests
- CMake build system
- GitHub Actions CI
- Optional AddressSanitizer + UndefinedBehaviorSanitizer
- Compiler warnings enabled
src/
├── Application.hpp / .cpp # CLI and user interaction
├── Book.hpp # Domain model
├── Library.hpp / .cpp # Business logic + persistence
├── CommandHistory.hpp / .cpp # Undo/redo state management
└── main.cpp # Application entry point
tests/
└── LibraryTests.cpp # Dependency-free automated tests
The code is intentionally separated into:
Presentation → Application → Domain/Business Logic → Persistence
This keeps the core library logic independently testable and makes future migration to a GUI, REST API, or database-backed service easier.
- C++17-compatible compiler
- CMake 3.16+
- Git
Common supported toolchains:
- GCC
- Clang
- MSVC
No third-party runtime dependency is required.
cmake -S . -B build
cmake --build build --config ReleaseRun:
.\build\Release\library_management.execmake -S . -B build
cmake --build build --config Release
./build/library_managementAfter building:
ctest --test-dir build --output-on-failureOr execute the test binary directly:
./build/library_testsOn Windows with a multi-config generator:
.\build\Release\library_tests.exeFor GCC/Clang:
cmake -S . -B build-sanitized -DENABLE_SANITIZERS=ON -DCMAKE_BUILD_TYPE=Debug
cmake --build build-sanitized
ctest --test-dir build-sanitized --output-on-failureThe sanitizer configuration uses:
- AddressSanitizer
- UndefinedBehaviorSanitizer
1. Add Book
2. Remove Book
3. Search Books
4. Borrow Book
5. Return Book
6. Sort by Code
7. Sort by Publication Year
8. Display All Books
9. Undo Last Change
10. Redo Change
11. Show Activity History
12. Show Statistics
13. Save Library to CSV
14. Load Library from CSV
0. Exit
A book contains:
| Field | Description |
|---|---|
code |
Unique positive identifier |
title |
Book title |
author |
Author name |
year |
Publication year |
available |
Current availability |
waitingList |
FIFO reservation queue |
When a borrowed book receives additional requests, borrowers are added in FIFO order.
When the book is returned:
- The first waiting borrower receives the book.
- That borrower is removed from the waiting list.
- The book remains marked as borrowed.
- Remaining requests preserve their order.
This models a basic reservation queue without requiring a separate queue library.
Undo/redo is implemented using complete before/after state snapshots.
This is deliberately more reliable than writing a separate reverse operation for every mutation.
For example, a return operation may both:
- change availability, and
- remove a borrower from the waiting list.
A snapshot captures both changes atomically.
A new mutation after an undo invalidates the redo branch, following standard editor-style behavior.
The system supports CSV import/export.
Example:
code,title,author,year,available,waiting_list
101,"Clean Code","Robert C. Martin",2008,1,""
102,"C++ Primer, 5th Edition","Stanley B. Lippman",2012,0,"Alice|Bob"The implementation handles quoted CSV values and escaped quotation marks.
Invalid headers, malformed rows, invalid numbers, invalid availability flags, duplicate codes, and capacity violations are rejected.
For n books:
| Operation | Complexity |
|---|---|
| Add | O(n) |
| Remove | O(n) |
| Search | O(n) |
| Sort | O(n log n) |
| Statistics | O(n) |
| Save | O(n) |
| Load | O(n) |
The application intentionally favors clarity and predictable behavior over premature optimization.
For a larger production system, the next step would be indexed lookup and database-backed persistence.
The repository includes:
- CMake-based reproducible builds
- Compiler warnings
- Automated unit tests
- GitHub Actions
- Sanitizer configuration
- No third-party runtime dependency
.gitignore- Sample dataset
- Test plan
Every pull request is automatically built and tested by GitHub Actions.
The original implementation used global fixed-size arrays, manual queue indices, and operation-specific undo logic.
This version replaces those patterns with:
std::vector- encapsulated domain logic
- RAII
- deterministic state snapshots
- centralized validation
- safe CSV parsing
- modular source files
- automated tests
- CI
The result is easier to maintain, test, extend, and review.
Possible next iterations:
- ISBN support
- Member management
- Due dates and overdue detection
- Fine calculation
- Authentication and role-based authorization
- SQLite/PostgreSQL persistence
- REST API
- Web dashboard
- Docker
- Structured logging
- Database indexes
- Pagination
- Integration tests
- GoogleTest/Catch2
- clang-tidy
- clang-format
- Code coverage reporting
- Release artifacts
- Package management with vcpkg or Conan
- C++17
- Modular architecture
- Encapsulation
- STL-based data structures
- Input validation
- Search
- Sorting
- FIFO waiting list
- Undo/redo
- CSV persistence
- Automated tests
- CMake
- GitHub Actions CI
- Sanitizer configuration
- Compiler warnings
-
.gitignore - Professional documentation
MIT License.
See LICENSE for details.
Trane-N-lab
This repository is maintained as a C++ software engineering portfolio project.