Skip to content

C++ Integration with Grapa

Overview

Grapa provides powerful C++ integration capabilities through its universal development kit, offering a complete C++ API for embedding Grapa in applications. This integration combines Grapa's efficient runtime with C++'s performance and type safety for high-performance applications.

Key Benefits

1. High-Performance Embedding

Grapa's C++ API provides direct access to the runtime with minimal overhead:

#include "grapa/GrapaLink.h"

int main() {
    // Initialize Grapa runtime
    GrapaLink grapa;

    // Execute Grapa code with full performance
    GrapaValue result = grapa.eval("2 + 2");
    std::cout << "Result: " << result << std::endl;

    return 0;
}

Advantages: - Direct runtime access with minimal overhead - Type-safe C++ interface for Grapa values - Memory management handled automatically - Exception safety with proper error handling

2. Complete API Access

Core Runtime Functions

Full access to Grapa's core functionality:

#include "grapa/GrapaLink.h"

int main() {
    GrapaLink grapa;

    // File system operations
    GrapaValue file = grapa.file();
    GrapaValue result = grapa.eval("file().ls('.')");

    // Database operations
    GrapaValue db = grapa.eval("{}.table('ROW')");
    grapa.eval("db.mkfield('name', 'STR')");

    // Mathematical operations
    GrapaValue math_result = grapa.eval("123456789012345678901234567890 * 987654321098765432109876543210");

    return 0;
}

Advanced Features

Access to Grapa's advanced capabilities:

// Parallel processing
GrapaValue data = grapa.eval("(1000000).range(0,1)");
GrapaValue processed = grapa.eval("data.map(op(x) { x * x; }, 8)");

// Dynamic code execution
GrapaValue compiled = grapa.eval("$sys().compile('x * 2 + offset')");
GrapaValue result = grapa.eval("$sys().eval(compiled, {'x': 10, 'offset': 5})");

// String processing
GrapaValue text = grapa.eval("'Hello, World!'");
GrapaValue upper = grapa.eval("text.upper()");

3. Universal Development Kit

The universal development kit provides everything needed for C++ development:

// Complete API headers
#include "grapa/GrapaLink.h"    // Main API
#include "grapa/GrapaValue.h"   // Value types
#include "grapa/GrapaType.h"    // Type system
#include "grapa/GrapaFile.h"    // File operations
#include "grapa/GrapaDatabase.h" // Database operations

Kit Contents: - Complete C++ API headers in include/grapa/ - Sample application (main.cpp) demonstrating embedding - CMake build system with cross-platform support - All platform libraries (Windows, macOS, Linux, AWS) - Third-party libraries (FLTK, OpenSSL, BLST, PCRE2)

Getting Started

1. Download and Extract

# Download universal installer (recommended)
curl -O https://github.com/grapa-dev/grapa/releases/download/v0.1.53/install-grapa-0.1.53.py
python3 install-grapa-0.1.53.py

# Or download platform-specific package manually
# curl -L -o grapa-0.1.53-<platform>.zip https://github.com/grapa-dev/grapa/releases/download/v0.1.53/grapa-0.1.53-<platform>.zip
# unzip grapa-0.1.53-<platform>.zip
# cd grapa-0.1.53

2. Build the Example

# Create build directory
mkdir build && cd build

# Configure with CMake
cmake ..

# Build the project
cmake --build .

# Run the example
./grapa_example  # On Unix/macOS
grapa_example.exe  # On Windows

3. Your First C++ Application

#include "grapa/GrapaLink.h"
#include <iostream>

int main() {
    try {
        // Initialize Grapa runtime
        GrapaLink grapa;

        // Execute simple Grapa code
        GrapaValue result = grapa.eval("2 + 2");
        std::cout << "2 + 2 = " << result << std::endl;

        // Execute more complex code
        GrapaValue complex_result = grapa.eval("'Hello, ' + 'World!'.upper()");
        std::cout << "Complex result: " << complex_result << std::endl;

        // File operations
        GrapaValue file_result = grapa.eval("$file().ls('.')");
        std::cout << "Files in current directory: " << file_result << std::endl;

    } catch (const std::exception& e) {
        std::cerr << "Error: " << e.what() << std::endl;
        return 1;
    }

    return 0;
}

Use Cases

1. High-Performance Applications

Scientific Computing

#include "grapa/GrapaLink.h"

class ScientificCalculator {
private:
    GrapaLink grapa;

public:
    ScientificCalculator() {
        // Initialize with scientific computing functions
        grapa.eval(R"(
            // Define scientific functions
            factorial = op(n) {
                if (n <= 1) return 1;
                return n * factorial(n - 1);
            };

            fibonacci = op(n) {
                if (n <= 1) return n;
                return fibonacci(n - 1) + fibonacci(n - 2);
            };
        )");
    }

    double calculateFactorial(int n) {
        GrapaValue result = grapa.eval("factorial(" + std::to_string(n) + ")");
        return result.toDouble();
    }

    long long calculateFibonacci(int n) {
        GrapaValue result = grapa.eval("fibonacci(" + std::to_string(n) + ")");
        return result.toLongLong();
    }
};

Data Processing Pipeline

#include "grapa/GrapaLink.h"
#include <vector>
#include <string>

class DataProcessor {
private:
    GrapaLink grapa;

public:
    DataProcessor() {
        // Initialize data processing functions
        grapa.eval(R"(
            // Data processing functions
            process_data = op(data) {
                // Grapa's parallel processing
                return data.map(op(x) { x * 2; }, 4);
            };

            filter_data = op(data, threshold) {
                return data.filter(op(x) { x > threshold; });
            };
        )");
    }

    std::vector<double> processVector(const std::vector<double>& input) {
        // Convert C++ vector to Grapa array
        std::string grapa_array = "[";
        for (size_t i = 0; i < input.size(); ++i) {
            if (i > 0) grapa_array += ", ";
            grapa_array += std::to_string(input[i]);
        }
        grapa_array += "]";

        // Process with Grapa
        GrapaValue result = grapa.eval("process_data(" + grapa_array + ")");

        // Convert back to C++ vector
        std::vector<double> output;
        // Implementation depends on GrapaValue API
        return output;
    }
};

2. System Applications

Configuration Management

#include "grapa/GrapaLink.h"
#include <fstream>
#include <string>

class ConfigManager {
private:
    GrapaLink grapa;
    std::string config_path;

public:
    ConfigManager(const std::string& path) : config_path(path) {
        // Load configuration with Grapa
        grapa.eval("config = $file().getfield('" + config_path + "').json()");
    }

    std::string getString(const std::string& key) {
        GrapaValue result = grapa.eval("config." + key);
        return result.toString();
    }

    int getInt(const std::string& key) {
        GrapaValue result = grapa.eval("config." + key);
        return result.toInt();
    }

    bool getBool(const std::string& key) {
        GrapaValue result = grapa.eval("config." + key);
        return result.toBool();
    }

    void setString(const std::string& key, const std::string& value) {
        grapa.eval("config." + key + " = '" + value + "'");
        saveConfig();
    }

private:
    void saveConfig() {
        grapa.eval("$file().setfield('" + config_path + "', config.json())");
    }
};

Log Processing

#include "grapa/GrapaLink.h"
#include <iostream>
#include <fstream>

class LogProcessor {
private:
    GrapaLink grapa;

public:
    LogProcessor() {
        // Initialize log processing functions
        grapa.eval(R"(
            // Log processing functions
            parse_log_line = op(line) {
                parts = line.split(' ');
                return {
                    'timestamp': parts[0] + ' ' + parts[1],
                    'level': parts[2],
                    'message': parts.slice(3).join(' ')
                };
            };

            filter_by_level = op(logs, level) {
                return logs.filter(op(log) { log.level == level; });
            };
        )");
    }

    void processLogFile(const std::string& filename) {
        // Read log file
        std::ifstream file(filename);
        std::string content((std::istreambuf_iterator<char>(file)),
                           std::istreambuf_iterator<char>());

        // Process with Grapa
        grapa.eval("log_content = `" + content + "`");
        grapa.eval("log_lines = log_content.split('\\n')");
        grapa.eval("parsed_logs = log_lines.map(parse_log_line)");

        // Filter errors
        GrapaValue errors = grapa.eval("filter_by_level(parsed_logs, 'ERROR')");
        std::cout << "Found " << errors << " error entries" << std::endl;
    }
};

3. Web Server Integration

HTTP Server with Grapa Backend

#include "grapa/GrapaLink.h"
#include <cpprest/http_listener.h>
#include <cpprest/json.h>

class GrapaWebServer {
private:
    GrapaLink grapa;
    web::http::experimental::listener::http_listener listener;

public:
    GrapaWebServer(const std::string& url) : listener(url) {
        // Initialize Grapa with web functions
        grapa.eval(R"(
            // Web processing functions
            process_request = op(data) {
                // Process request data with Grapa
                return data.map(op(item) { item.upper(); });
            };

            validate_input = op(input) {
                return input.len() > 0 && input.len() < 1000;
            };
        )");

        // Set up HTTP endpoints
        listener.support(web::http::methods::POST, 
                        std::bind(&GrapaWebServer::handlePost, this, std::placeholders::_1));
    }

    void handlePost(web::http::http_request request) {
        request.extract_string().then([this, request](const std::string& body) {
            try {
                // Process with Grapa
                grapa.eval("input_data = `" + body + "`");
                GrapaValue result = grapa.eval("process_request(input_data)");

                // Send response
                web::json::value response;
                response["result"] = web::json::value::string(result.toString());
                request.reply(web::http::status_codes::OK, response);

            } catch (const std::exception& e) {
                web::json::value error;
                error["error"] = web::json::value::string(e.what());
                request.reply(web::http::status_codes::InternalError, error);
            }
        });
    }

    void start() {
        listener.open().wait();
    }

    void stop() {
        listener.close().wait();
    }
};

Performance Optimization

Memory Management

#include "grapa/GrapaLink.h"

class OptimizedProcessor {
private:
    GrapaLink grapa;

public:
    OptimizedProcessor() {
        // Pre-compile frequently used functions
        grapa.eval(R"(
            // Pre-compile for performance
            compiled_processor = $sys().compile('data.map(op(x) { x * 2; })');
            compiled_filter = $sys().compile('data.filter(op(x) { x > threshold; })');
        )");
    }

    GrapaValue processData(const GrapaValue& data) {
        // Use pre-compiled function for better performance
        return grapa.eval("$sys().eval(compiled_processor, {'data': " + data.toString() + "})");
    }

    GrapaValue filterData(const GrapaValue& data, double threshold) {
        // Use pre-compiled function with parameters
        return grapa.eval("$sys().eval(compiled_filter, {'data': " + data.toString() + 
                         ", 'threshold': " + std::to_string(threshold) + "})");
    }
};

Error Handling

#include "grapa/GrapaLink.h"
#include <stdexcept>

class SafeGrapaWrapper {
private:
    GrapaLink grapa;

public:
    GrapaValue safeEval(const std::string& code) {
        try {
            return grapa.eval(code);
        } catch (const std::exception& e) {
            throw std::runtime_error("Grapa evaluation failed: " + std::string(e.what()));
        }
    }

    bool isValidCode(const std::string& code) {
        try {
            grapa.eval(code);
            return true;
        } catch (...) {
            return false;
        }
    }

    GrapaValue safeEvalWithDefault(const std::string& code, const GrapaValue& default_value) {
        try {
            return grapa.eval(code);
        } catch (...) {
            return default_value;
        }
    }
};

Build System Integration

CMakeLists.txt Example

cmake_minimum_required(VERSION 3.10)
project(grapa_cpp_app)

set(CMAKE_CXX_STANDARD 17)

# Find Grapa
find_path(GRAPA_INCLUDE_DIR grapa/GrapaLink.h
    PATHS ${CMAKE_CURRENT_SOURCE_DIR}/include
    NO_DEFAULT_PATH
)

find_library(GRAPA_LIBRARY
    NAMES grapa_static
    PATHS ${CMAKE_CURRENT_SOURCE_DIR}/platforms/${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}
    NO_DEFAULT_PATH
)

# Include directories
include_directories(${GRAPA_INCLUDE_DIR})
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)

# Create executable
add_executable(grapa_app main.cpp)

# Link libraries
target_link_libraries(grapa_app ${GRAPA_LIBRARY})

# Platform-specific libraries
if(WIN32)
    target_link_libraries(grapa_app
        gdiplus
        ComCtl32
        crypt32
    )
elseif(APPLE)
    find_library(COCOA_LIBRARY Cocoa)
    find_library(IOKIT_LIBRARY IOKit)
    find_library(CARBON_LIBRARY Carbon)
    target_link_libraries(grapa_app
        ${COCOA_LIBRARY}
        ${IOKIT_LIBRARY}
        ${CARBON_LIBRARY}
    )
elseif(UNIX)
    find_package(X11 REQUIRED)
    target_link_libraries(grapa_app ${X11_LIBRARIES})
endif()

Cross-Platform Build

# Build for current platform
mkdir build && cd build
cmake ..
cmake --build .

# Cross-compile (example for different platforms)
# Windows (from Linux with MinGW)
cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/windows.cmake ..

# macOS (from Linux with osxcross)
cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/macos.cmake ..

Best Practices

Initialization and Cleanup

class GrapaApplication {
private:
    std::unique_ptr<GrapaLink> grapa;

public:
    GrapaApplication() {
        // Initialize once
        grapa = std::make_unique<GrapaLink>();

        // Set up common functions
        grapa->eval(R"(
            // Common utility functions
            format_output = op(data) {
                return 'Processed: ' + data.str();
            };
        )");
    }

    ~GrapaApplication() {
        // Automatic cleanup via unique_ptr
    }

    // Non-copyable
    GrapaApplication(const GrapaApplication&) = delete;
    GrapaApplication& operator=(const GrapaApplication&) = delete;
};

Thread Safety

#include "grapa/GrapaLink.h"
#include <mutex>
#include <thread>

class ThreadSafeGrapa {
private:
    GrapaLink grapa;
    std::mutex grapa_mutex;

public:
    GrapaValue safeEval(const std::string& code) {
        std::lock_guard<std::mutex> lock(grapa_mutex);
        return grapa.eval(code);
    }

    void processInParallel(const std::vector<std::string>& tasks) {
        std::vector<std::thread> threads;

        for (const auto& task : tasks) {
            threads.emplace_back([this, task]() {
                GrapaValue result = safeEval(task);
                // Process result...
            });
        }

        for (auto& thread : threads) {
            thread.join();
        }
    }
};

Performance Monitoring

#include "grapa/GrapaLink.h"
#include <chrono>
#include <iostream>

class PerformanceMonitor {
private:
    GrapaLink grapa;

public:
    template<typename Func>
    auto measureExecution(Func&& func) {
        auto start = std::chrono::high_resolution_clock::now();
        auto result = func();
        auto end = std::chrono::high_resolution_clock::now();

        auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
        std::cout << "Execution time: " << duration.count() << " microseconds" << std::endl;

        return result;
    }

    void benchmarkGrapaOperations() {
        // Benchmark different operations
        measureExecution([this]() {
            return grapa.eval("(1000000).range(0,1).map(op(x) { x * x; })");
        });

        measureExecution([this]() {
            return grapa.eval("'Hello, World!'.upper().split(', ')");
        });
    }
};

Conclusion

Grapa's C++ integration provides: - High-performance embedding with minimal overhead - Complete API access to all Grapa features - Type-safe interface with proper error handling - Cross-platform support through universal development kit - Easy integration with existing C++ applications

The universal development kit makes it simple to get started with C++ integration, while the comprehensive API allows for sophisticated applications that leverage Grapa's powerful runtime capabilities.


See also