cpp
examples
examples.cpp⚙️cpp
/**
* CMake Example Project
*
* This file demonstrates code that would be built with CMake.
* See the accompanying CMakeLists.txt example below.
*/
// ============================================================================
// EXAMPLE PROJECT STRUCTURE
// ============================================================================
/*
my_calculator/
├── CMakeLists.txt (shown below)
├── include/
│ └── calculator/
│ ├── calculator.hpp
│ └── operations.hpp
├── src/
│ ├── calculator.cpp
│ ├── operations.cpp
│ └── main.cpp
├── tests/
│ ├── CMakeLists.txt
│ └── test_calculator.cpp
└── build/ (generated)
*/
// ============================================================================
// FILE: CMakeLists.txt (Root)
// ============================================================================
/*
cmake_minimum_required(VERSION 3.16)
project(Calculator
VERSION 1.0.0
DESCRIPTION "A simple calculator library"
LANGUAGES CXX
)
# Set C++ standard
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
# Generate compile_commands.json for IDEs
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# Options
option(BUILD_TESTS "Build unit tests" ON)
option(BUILD_EXAMPLES "Build example programs" ON)
# Create the library
add_library(calculator
src/calculator.cpp
src/operations.cpp
)
# Set include directories
target_include_directories(calculator
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src
)
# Compiler warnings
target_compile_options(calculator PRIVATE
$<$<CXX_COMPILER_ID:GNU>:-Wall -Wextra -Wpedantic>
$<$<CXX_COMPILER_ID:Clang>:-Wall -Wextra -Wpedantic>
$<$<CXX_COMPILER_ID:MSVC>:/W4>
)
# Create the executable
add_executable(calc_app src/main.cpp)
target_link_libraries(calc_app PRIVATE calculator)
# Tests
if(BUILD_TESTS)
enable_testing()
add_subdirectory(tests)
endif()
# Installation
include(GNUInstallDirs)
install(TARGETS calculator calc_app
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
*/
// ============================================================================
// FILE: include/calculator/calculator.hpp
// ============================================================================
#ifndef CALCULATOR_HPP
#define CALCULATOR_HPP
#include <string>
#include <vector>
#include <functional>
namespace calc {
class Calculator {
public:
Calculator();
// Basic operations
double add(double a, double b) const;
double subtract(double a, double b) const;
double multiply(double a, double b) const;
double divide(double a, double b) const;
// Memory operations
void memoryStore(double value);
double memoryRecall() const;
void memoryClear();
// History
const std::vector<std::string>& getHistory() const;
void clearHistory();
// Expression evaluation
double evaluate(const std::string& expression);
// Register custom operation
void registerOperation(const std::string& name,
std::function<double(double, double)> op);
private:
double memory_;
std::vector<std::string> history_;
std::map<std::string, std::function<double(double, double)>> customOps_;
void recordHistory(const std::string& operation);
};
} // namespace calc
#endif // CALCULATOR_HPP
// ============================================================================
// FILE: include/calculator/operations.hpp
// ============================================================================
#ifndef OPERATIONS_HPP
#define OPERATIONS_HPP
#include <cmath>
#include <stdexcept>
namespace calc {
namespace ops {
// Unary operations
inline double negate(double x) { return -x; }
inline double abs(double x) { return std::abs(x); }
inline double sqrt(double x) {
if (x < 0) throw std::domain_error("sqrt of negative");
return std::sqrt(x);
}
inline double square(double x) { return x * x; }
inline double cube(double x) { return x * x * x; }
// Trigonometric
inline double sin(double x) { return std::sin(x); }
inline double cos(double x) { return std::cos(x); }
inline double tan(double x) { return std::tan(x); }
// Logarithmic
inline double log(double x) {
if (x <= 0) throw std::domain_error("log of non-positive");
return std::log(x);
}
inline double log10(double x) {
if (x <= 0) throw std::domain_error("log10 of non-positive");
return std::log10(x);
}
inline double exp(double x) { return std::exp(x); }
// Binary operations
inline double power(double base, double exp) { return std::pow(base, exp); }
inline double mod(double a, double b) { return std::fmod(a, b); }
// Statistical
double mean(const double* values, size_t count);
double variance(const double* values, size_t count);
double stddev(const double* values, size_t count);
} // namespace ops
} // namespace calc
#endif // OPERATIONS_HPP
// ============================================================================
// FILE: src/calculator.cpp
// ============================================================================
/*
#include "calculator/calculator.hpp"
#include <sstream>
#include <stdexcept>
namespace calc {
Calculator::Calculator() : memory_(0.0) {}
double Calculator::add(double a, double b) const {
return a + b;
}
double Calculator::subtract(double a, double b) const {
return a - b;
}
double Calculator::multiply(double a, double b) const {
return a * b;
}
double Calculator::divide(double a, double b) const {
if (b == 0.0) {
throw std::runtime_error("Division by zero");
}
return a / b;
}
void Calculator::memoryStore(double value) {
memory_ = value;
}
double Calculator::memoryRecall() const {
return memory_;
}
void Calculator::memoryClear() {
memory_ = 0.0;
}
const std::vector<std::string>& Calculator::getHistory() const {
return history_;
}
void Calculator::clearHistory() {
history_.clear();
}
void Calculator::recordHistory(const std::string& operation) {
history_.push_back(operation);
}
void Calculator::registerOperation(const std::string& name,
std::function<double(double, double)> op) {
customOps_[name] = op;
}
} // namespace calc
*/
// ============================================================================
// FILE: src/operations.cpp
// ============================================================================
/*
#include "calculator/operations.hpp"
#include <numeric>
namespace calc {
namespace ops {
double mean(const double* values, size_t count) {
if (count == 0) return 0.0;
double sum = 0.0;
for (size_t i = 0; i < count; ++i) {
sum += values[i];
}
return sum / count;
}
double variance(const double* values, size_t count) {
if (count < 2) return 0.0;
double m = mean(values, count);
double sumSq = 0.0;
for (size_t i = 0; i < count; ++i) {
double diff = values[i] - m;
sumSq += diff * diff;
}
return sumSq / (count - 1);
}
double stddev(const double* values, size_t count) {
return std::sqrt(variance(values, count));
}
} // namespace ops
} // namespace calc
*/
// ============================================================================
// FILE: src/main.cpp
// ============================================================================
#include <iostream>
#include <string>
#include <sstream>
// Simulating the calculator library interface
namespace calc {
class Calculator {
double memory_ = 0;
public:
double add(double a, double b) { return a + b; }
double subtract(double a, double b) { return a - b; }
double multiply(double a, double b) { return a * b; }
double divide(double a, double b) {
if (b == 0) throw std::runtime_error("Division by zero");
return a / b;
}
void memoryStore(double v) { memory_ = v; }
double memoryRecall() { return memory_; }
};
}
int main() {
std::cout << "╔══════════════════════════════════════════════════════════════╗" << std::endl;
std::cout << "║ CMAKE PROJECT EXAMPLE ║" << std::endl;
std::cout << "╚══════════════════════════════════════════════════════════════╝" << std::endl;
calc::Calculator calc;
std::cout << "\nCalculator Demo (built with CMake)" << std::endl;
std::cout << "====================================" << std::endl;
std::cout << "\nBasic Operations:" << std::endl;
std::cout << " 10 + 5 = " << calc.add(10, 5) << std::endl;
std::cout << " 10 - 5 = " << calc.subtract(10, 5) << std::endl;
std::cout << " 10 * 5 = " << calc.multiply(10, 5) << std::endl;
std::cout << " 10 / 5 = " << calc.divide(10, 5) << std::endl;
std::cout << "\nMemory Operations:" << std::endl;
calc.memoryStore(42.0);
std::cout << " Stored: 42.0" << std::endl;
std::cout << " Recall: " << calc.memoryRecall() << std::endl;
std::cout << "\n═══════════════════════════════════════════════════════════════" << std::endl;
std::cout << "To build this project with CMake:" << std::endl;
std::cout << " mkdir build && cd build" << std::endl;
std::cout << " cmake .." << std::endl;
std::cout << " cmake --build ." << std::endl;
return 0;
}
// ============================================================================
// FILE: tests/CMakeLists.txt
// ============================================================================
/*
# Find Google Test
find_package(GTest REQUIRED)
# Create test executable
add_executable(calculator_tests
test_calculator.cpp
)
target_link_libraries(calculator_tests
PRIVATE
calculator
GTest::GTest
GTest::Main
)
# Register tests with CTest
include(GoogleTest)
gtest_discover_tests(calculator_tests)
*/
// ============================================================================
// FILE: tests/test_calculator.cpp
// ============================================================================
/*
#include <gtest/gtest.h>
#include "calculator/calculator.hpp"
class CalculatorTest : public ::testing::Test {
protected:
calc::Calculator calc;
};
TEST_F(CalculatorTest, Addition) {
EXPECT_DOUBLE_EQ(calc.add(2, 3), 5);
EXPECT_DOUBLE_EQ(calc.add(-1, 1), 0);
EXPECT_DOUBLE_EQ(calc.add(0, 0), 0);
}
TEST_F(CalculatorTest, Subtraction) {
EXPECT_DOUBLE_EQ(calc.subtract(5, 3), 2);
EXPECT_DOUBLE_EQ(calc.subtract(0, 5), -5);
}
TEST_F(CalculatorTest, Multiplication) {
EXPECT_DOUBLE_EQ(calc.multiply(3, 4), 12);
EXPECT_DOUBLE_EQ(calc.multiply(-2, 3), -6);
EXPECT_DOUBLE_EQ(calc.multiply(0, 100), 0);
}
TEST_F(CalculatorTest, Division) {
EXPECT_DOUBLE_EQ(calc.divide(10, 2), 5);
EXPECT_DOUBLE_EQ(calc.divide(7, 2), 3.5);
}
TEST_F(CalculatorTest, DivisionByZero) {
EXPECT_THROW(calc.divide(1, 0), std::runtime_error);
}
TEST_F(CalculatorTest, Memory) {
calc.memoryStore(42);
EXPECT_DOUBLE_EQ(calc.memoryRecall(), 42);
calc.memoryClear();
EXPECT_DOUBLE_EQ(calc.memoryRecall(), 0);
}
*/
// ============================================================================
// ADDITIONAL CMAKE EXAMPLES
// ============================================================================
/*
# Example: Fetching dependencies
cmake_minimum_required(VERSION 3.16)
project(WithDependencies)
include(FetchContent)
# Fetch nlohmann/json
FetchContent_Declare(
json
GIT_REPOSITORY https://github.com/nlohmann/json.git
GIT_TAG v3.11.2
)
# Fetch fmt library
FetchContent_Declare(
fmt
GIT_REPOSITORY https://github.com/fmtlib/fmt.git
GIT_TAG 10.1.1
)
FetchContent_MakeAvailable(json fmt)
add_executable(app main.cpp)
target_link_libraries(app PRIVATE nlohmann_json::nlohmann_json fmt::fmt)
*/
/*
# Example: Header-only library
cmake_minimum_required(VERSION 3.16)
project(HeaderOnly)
add_library(mylib INTERFACE)
target_include_directories(mylib INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
)
target_compile_features(mylib INTERFACE cxx_std_17)
*/
/*
# Example: Finding and using Boost
cmake_minimum_required(VERSION 3.16)
project(WithBoost)
find_package(Boost 1.70 REQUIRED COMPONENTS filesystem system)
add_executable(app main.cpp)
target_link_libraries(app PRIVATE Boost::filesystem Boost::system)
*/
/*
# Example: Multi-configuration with presets (CMakePresets.json)
{
"version": 3,
"configurePresets": [
{
"name": "debug",
"displayName": "Debug",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/debug",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug"
}
},
{
"name": "release",
"displayName": "Release",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/release",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release"
}
}
],
"buildPresets": [
{
"name": "debug",
"configurePreset": "debug"
},
{
"name": "release",
"configurePreset": "release"
}
]
}
# Usage:
# cmake --preset debug
# cmake --build --preset debug
*/