Skip to content
Open
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
13 changes: 13 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ INCLUDE(GNUInstallDirs)

LIST( APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake )

# Load C++20 module support
INCLUDE( SIOModules )

# options
OPTION( SIO_EXAMPLES "Switch ON to build SIO examples" ON )
OPTION( INSTALL_DOC "Set to OFF to skip build/install Documentation" OFF )
Expand All @@ -38,6 +41,16 @@ ENDIF()
# ZLIB package
IF( SIO_BUILTIN_ZLIB )
ADD_SUBDIRECTORY( zlib )
# Install ZLIB when SIO modules are enabled (needed for export)
# Note: This makes ZLIB visible to downstream users as SIO::ZLIB when modules are enabled.
# This is required by CMake's export mechanism for targets with FILE_SET CXX_MODULES.
# The ZLIB target is static and should not conflict with system ZLIB libraries.
IF( SIO_ENABLE_CXX_MODULES )
INSTALL( TARGETS ZLIB
EXPORT SIOTargets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
ENDIF()
ELSE()
FIND_PACKAGE( ZLIB REQUIRED )
ENDIF()
Expand Down
87 changes: 87 additions & 0 deletions cmake/SIOModules.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#---------------------------------------------------------------------------------------------------
# CMake support for C++20 modules in SIO
#
# This file provides macros and options for generating and using C++20 module interfaces
# for the SIO library.
#---------------------------------------------------------------------------------------------------

# Option to enable C++20 module generation
option(SIO_ENABLE_CXX_MODULES "Generate C++20 module interface files (.ixx) for SIO" OFF)

# Check if modules are actually supported
if(SIO_ENABLE_CXX_MODULES)
# Check CMake version
if(CMAKE_VERSION VERSION_LESS 3.29)
message(WARNING "C++20 modules require CMake 3.29 or later (found ${CMAKE_VERSION}). Disabling module support.")
set(SIO_ENABLE_CXX_MODULES OFF CACHE BOOL "C++20 modules disabled due to CMake version" FORCE)
endif()

# Check generator
if(CMAKE_GENERATOR STREQUAL "Unix Makefiles")
message(WARNING "C++20 modules are not supported with the Unix Makefiles generator. Please use Ninja. Disabling module support.")
set(SIO_ENABLE_CXX_MODULES OFF CACHE BOOL "C++20 modules disabled due to generator" FORCE)
endif()

# Check compiler support
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 14.0)
message(WARNING "C++20 modules require GCC 14 or later (found ${CMAKE_CXX_COMPILER_VERSION}). Disabling module support.")
set(SIO_ENABLE_CXX_MODULES OFF CACHE BOOL "C++20 modules disabled due to compiler version" FORCE)
endif()
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 18.0)
message(WARNING "C++20 modules require Clang 18 or later (found ${CMAKE_CXX_COMPILER_VERSION}). Disabling module support.")
set(SIO_ENABLE_CXX_MODULES OFF CACHE BOOL "C++20 modules disabled due to compiler version" FORCE)
endif()
else()
message(WARNING "C++20 modules have only been tested with GCC 14+ and Clang 18+. Found ${CMAKE_CXX_COMPILER_ID}. Proceed at your own risk.")
endif()
endif()

if(SIO_ENABLE_CXX_MODULES)
message(STATUS "C++20 module support is ENABLED for SIO")
message(STATUS " - CMake version: ${CMAKE_VERSION}")
message(STATUS " - Generator: ${CMAKE_GENERATOR}")
message(STATUS " - Compiler: ${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}")
else()
message(STATUS "C++20 module support is DISABLED for SIO")
endif()

#---------------------------------------------------------------------------------------------------
# SIO_ADD_MODULE_INTERFACE( target module_file )
#
# Add a C++20 module interface to a SIO target.
#
# This function conditionally adds a module interface file to the specified target when
# SIO_ENABLE_CXX_MODULES is ON. The module interface is added as a PUBLIC CXX_MODULES file set,
# which makes it available for installation and use by downstream projects.
#
# When SIO_ENABLE_CXX_MODULES is OFF, this function returns immediately without any action.
#
# Arguments:
# target - The target to which the module interface should be added
# module_file - The .ixx file implementing the module interface (absolute or relative path)
#
# Example:
# SIO_ADD_MODULE_INTERFACE(sio ${CMAKE_CURRENT_SOURCE_DIR}/sio_module.ixx)
#
# Note:
# The module_file should be installed separately using INSTALL(TARGETS ... FILE_SET CXX_MODULES)
# when SIO_ENABLE_CXX_MODULES is ON.
#---------------------------------------------------------------------------------------------------
function(SIO_ADD_MODULE_INTERFACE target module_file)
if(NOT SIO_ENABLE_CXX_MODULES)
return()
endif()

message(STATUS "Adding C++20 module 'sio' to target '${target}'")

# Add the module file to the target as a CXX_MODULES file set
# Use PUBLIC so the module gets installed and can be used by downstream projects
target_sources(${target}
PUBLIC
FILE_SET CXX_MODULES
BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}
FILES ${module_file}
)
endfunction()
22 changes: 19 additions & 3 deletions source/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,25 @@ IF( SIO_MACROS_WITH_EXCEPTION )
TARGET_COMPILE_DEFINITIONS(sio PUBLIC "-DSIO_MACROS_WITH_EXCEPTION=1")
ENDIF()

SIO_INSTALL_SHARED_LIBRARY( sio
EXPORT SIOTargets
DESTINATION ${CMAKE_INSTALL_LIBDIR} )
# Add C++20 module interface if enabled (before install)
IF( SIO_ENABLE_CXX_MODULES )
SIO_ADD_MODULE_INTERFACE( sio ${CMAKE_CURRENT_SOURCE_DIR}/sio_module.ixx )
# Install library with module file set
INSTALL( TARGETS sio
EXPORT SIOTargets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
FILE_SET CXX_MODULES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/sio/modules
PERMISSIONS
OWNER_READ OWNER_WRITE OWNER_EXECUTE
GROUP_READ GROUP_EXECUTE
WORLD_READ WORLD_EXECUTE
)
ELSE()
# Install library without modules
SIO_INSTALL_SHARED_LIBRARY( sio
EXPORT SIOTargets
DESTINATION ${CMAKE_INSTALL_LIBDIR} )
ENDIF()

# install SIO headers
SIO_INSTALL_DIRECTORY( include/sio DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} )
Expand Down
32 changes: 16 additions & 16 deletions source/include/sio/definitions.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,35 +108,35 @@ namespace sio {
using block_list = std::vector<block_ptr> ;

/// The null byte definition
static constexpr byte null_byte = '\0' ;
inline constexpr byte null_byte = '\0' ;

static constexpr byte padding_bytes [4] = {null_byte} ;
inline constexpr byte padding_bytes [4] = {null_byte} ;
/// Kilo byte unit
static constexpr std::size_t kbyte = 0x00000400 ;
inline constexpr std::size_t kbyte = 0x00000400 ;
/// Mega byte unit
static constexpr std::size_t mbyte = 0x00100000 ;
inline constexpr std::size_t mbyte = 0x00100000 ;
/// The compression bit mask
static constexpr unsigned int compression_bit = 0x00000001 ;
inline constexpr unsigned int compression_bit = 0x00000001 ;
/// The bit alignment mask
static constexpr unsigned int bit_align = 0x00000003 ;
inline constexpr unsigned int bit_align = 0x00000003 ;
/// The additional padding added in buffer IO
static constexpr unsigned int padding = 3 ;
inline constexpr unsigned int padding = 3 ;
/// The additional padding mask
static constexpr unsigned int padding_mask = 0xfffffffc ;
inline constexpr unsigned int padding_mask = 0xfffffffc ;
/// The record marker
static constexpr unsigned int record_marker = 0xabadcafe ;
inline constexpr unsigned int record_marker = 0xabadcafe ;
/// The block marker
static constexpr unsigned int block_marker = 0xdeadbeef ;
inline constexpr unsigned int block_marker = 0xdeadbeef ;
/// The maximum length of a record name
static constexpr std::size_t max_record_name_len = 64 ;
inline constexpr std::size_t max_record_name_len = 64 ;
/// The maximum length of a record_info in memory
static constexpr std::size_t max_record_info_len = 2*sizeof(sio::ifstream::pos_type) + 5*sizeof(unsigned int) + max_record_name_len ;
inline constexpr std::size_t max_record_info_len = 2*sizeof(sio::ifstream::pos_type) + 5*sizeof(unsigned int) + max_record_name_len ;

// TODO: Do we still need all of this ??
static constexpr std::size_t single_len = 1 ;
static constexpr std::size_t double_len = 2 ;
static constexpr std::size_t quad_len = 4 ;
static constexpr std::size_t octo_len = 8 ;
inline constexpr std::size_t single_len = 1 ;
inline constexpr std::size_t double_len = 2 ;
inline constexpr std::size_t quad_len = 4 ;
inline constexpr std::size_t octo_len = 8 ;

/**
* @brief record_info struct.
Expand Down
4 changes: 2 additions & 2 deletions source/include/sio/memcpy.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ namespace sio {
*/
template <typename T>
struct sizeof_helper {
static constexpr std::size_t size = sizeof(T) ;
static inline constexpr std::size_t size = sizeof(T) ;
};

#define SIO_FORCE_SIZEOF( TYPE, SIZE ) \
template <> \
struct sizeof_helper<TYPE> { \
static constexpr std::size_t size = SIZE ; \
static inline constexpr std::size_t size = SIZE ; \
}

SIO_FORCE_SIZEOF( char, 1 ) ;
Expand Down
109 changes: 109 additions & 0 deletions source/sio_module.ixx
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Module interface for SIO - Simple I/O library
//
// This module exports the core SIO types and interfaces.

module;

// Global module fragment - includes go here
#include <cctype>
#include <cstdint>
#include <fstream>
#include <functional>
#include <iostream>
#include <map>
#include <memory>
#include <string>
#include <type_traits>
#include <vector>

#ifdef __APPLE__
#include <_types.h>
#include <_types/_uint16_t.h>
#include <_types/_uint32_t.h>
#include <_types/_uint64_t.h>
#include <_types/_uint8_t.h>
#include <sys/_types/_int16_t.h>
#include <sys/_types/_int64_t.h>
#else
#include <stdint.h>
#endif

// SIO headers
#include "sio/definitions.h"
#include "sio/exception.h"
#include "sio/version.h"
#include "sio/buffer.h"
#include "sio/block.h"
#include "sio/io_device.h"
#include "sio/memcpy.h"
#include "sio/api.h"
#include "sio/compression/zlib.h"

export module sio;

// Export SIO namespace and types
export namespace sio {
// Type aliases from definitions.h
using sio::byte;
using sio::byte_array;
using sio::byte_traits;
using sio::index_type;
using sio::options_type;
using sio::version_type;
using sio::ptr_type;
using sio::pointed_at_map;
using sio::pointer_to_map;
using sio::ifstream;
using sio::ofstream;
using sio::fstream;
using sio::block_ptr;
using sio::block_list;

// Constants from definitions.h
using sio::null_byte;
using sio::padding_bytes;
using sio::kbyte;
using sio::mbyte;
using sio::compression_bit;
using sio::bit_align;
using sio::padding;
using sio::padding_mask;
using sio::record_marker;
using sio::block_marker;
using sio::max_record_name_len;
using sio::max_record_info_len;
using sio::single_len;
using sio::double_len;
using sio::quad_len;
using sio::octo_len;

// Structs and enums from definitions.h
using sio::record_info;
using sio::validate;
using sio::valid_record_name;

// Exception types
using sio::exception;
using sio::error_code;

// Version class
using sio::version;

// Core classes
using sio::buffer;
using sio::buffer_span;
using sio::block;
using sio::read_device;
using sio::write_device;

// Memory copy utilities
using sio::memcpy;
using sio::sizeof_helper;

// API class and functions
using sio::api;

// Compression
using sio::zlib_compression;
}