Squashed 'externals/zycore/' changes from 0c372cde..1401fb85

1401fb85 Fix `a label can only be part of a statement` warning (#61)
5f650a18 CMake: Enable `CMAKE_MSVC_RUNTIME_LIBRARY` (MSVC)
6c958cfe Fix no-libc build on "other" platforms (#58)
59819206 Bump version to v1.4.0
4bc563f6 Fix build-system to better work with vcpkg (#56)
4a8b5e2a CMake: rename target `doc` -> `ZycoreDoc`
a754e112 Bump version to 1.3.0
3e95307d Add support for ppc(64) and riscv64 (#52)
8f39333a build: only enable CXX if needed
7bd75696 build: add doc target
7c33e13e Fix `ZYAN_TRUE`/`ZYAN_FALSE` signedness
a0feec7f Fix warning `C4668`
bdbd3ff4 Bump version to v1.2
60b6ef1c Fix for dynamic libraries too
310f362c Adding ARCHIVE DESTINATION to fix CMake error
b01063b8 Improved logic for enabling LTO
c58d7fb5 Don't enable C11 for MSVC
ee784564 Switch minimum C standard supported to C11
5c341bf1 Implement an initial set of cross-compiler atomic operations
b4949ccc Minor fixes
9a305f6a Add CI workflow
dd2211a0 Get rid of CMake export headers
f0fb3f78 Fix `ZYAN_VECTOR_FOREACH_MUTABLE` macro
3f263290 format: handle encoding on wasm
95d7fb6c format: handle hex encoding on wasm
0d37fc54 defines: add wasm/wasi detection
8983325b build: use -pthread when possible
3de49d41 build: use system GTest when available
8d46cb58 test: make tests runnable with ctest
636bb299 Remove `float`s from the project (kernel mode compatibility) (#36)
e2b37b10 Assert to ensure sane growth factors
94185407 Added limits for integer types
767719d9 build(cmake): export and install zyan_* functions (#33)
6c93d9a3 build(cmake): add version and soversion to the library
fc2798d4 build(cmake): fix PUBLIC include dir of installed lib
22ce9c2d Add `ZYAN_FORCE_ASSERTS` CMake option
9a301424 Remove disabling source files in no-libc mode in CMake
3be54fca Thread.c: add missing SDK prototypes for old versions of Windows
d7fc85fd Exclude API/Memory.c and API/Process.c from compilation in no-libc mode
8da0001a Add back #ifdef guards to "API" headers/sources for no-libc mode
f6a48866 Fix cmake config files (#27)
4f3746fa Merge pull request #26 from Tsn0w/master
a9bb54ad Replace fallthrough attribute to __fallthrough__
99a74acb Add `ZYDIS_NOINLINE` macro

git-subtree-dir: externals/zycore
git-subtree-split: 1401fb85ac313f6605ec795c52bf99ea3f292a69
This commit is contained in:
Alexandre Bouvier 2022-11-20 21:49:18 +01:00
parent 80d62f2249
commit cd2ede593a
35 changed files with 1120 additions and 228 deletions

1
.github/FUNDING.yml vendored Normal file
View file

@ -0,0 +1 @@
github: flobernd

86
.github/workflows/main.yml vendored Normal file
View file

@ -0,0 +1,86 @@
name: GitHub Actions CI
on:
push:
branches:
- master
pull_request:
types: [opened, synchronize, reopened]
jobs:
build-linux:
name: Build ${{ matrix.platform.name }} ${{ matrix.compiler.name }} ${{ matrix.flavor }} (${{ matrix.mode.name }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
platform:
- { name: x86, flags: "-m32" }
- { name: x64, flags: "-m64" }
compiler:
- { name: GNU, CC: gcc }
- { name: LLVM, CC: clang }
flavor:
- Debug
- Release
mode:
- { name: default, args: "" }
- { name: NO_LIBC, args: -DZYAN_NO_LIBC=ON }
steps:
- name: Checkout
uses: actions/checkout@v3.1.0
- if: matrix.platform.name == 'x86'
name: Bootstrap
run: |
sudo dpkg --add-architecture i386
sudo rm /etc/apt/sources.list.d/* && sudo apt-get update
sudo apt-get install -y g++-multilib g++
- name: Configure
env:
CC: ${{ matrix.compiler.CC }}
CXX: ${{ matrix.compiler.CXX }}
run: |
mkdir build
cd build
cmake -DCMAKE_C_FLAGS=${{ matrix.platform.flags }} -DCMAKE_CXX_FLAGS=${{ matrix.platform.flags }} -DZYAN_DEV_MODE=ON ${{ matrix.mode.args }} ..
- name: Build
run: |
cmake --build build --config ${{ matrix.flavor }}
build-windows:
name: Build ${{ matrix.platform.name }} ${{ matrix.compiler.name }} ${{ matrix.flavor }} (${{ matrix.mode.name }})
runs-on: windows-latest
strategy:
fail-fast: false
matrix:
platform:
- { name: x86, flags: "Win32" }
- { name: x64, flags: "x64" }
compiler:
- { name: MSVC }
flavor:
- Debug
- Release
mode:
- { name: default, args: "" }
- { name: NO_LIBC, args: -DZYAN_NO_LIBC=ON }
steps:
- name: Checkout
uses: actions/checkout@v3.1.0
- name: Configure
run: |
mkdir build
cd build
cmake -DCMAKE_GENERATOR_PLATFORM=${{ matrix.platform.flags }} -DZYAN_DEV_MODE=ON ${{ matrix.mode.args }} ..
- name: Build
run: |
cmake --build build --config ${{ matrix.flavor }}

View file

@ -2,13 +2,18 @@ if (TARGET Zycore)
return()
endif ()
cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
include(GenerateExportHeader)
cmake_minimum_required(VERSION 3.9 FATAL_ERROR)
if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.15")
# Enable runtime library selection via CMAKE_MSVC_RUNTIME_LIBRARY
cmake_policy(SET CMP0091 NEW)
endif ()
project(Zycore VERSION 1.4.0.0 LANGUAGES C)
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)
project(Zycore VERSION 1.0.0.0 LANGUAGES C CXX)
# =============================================================================================== #
# Overridable options #
# =============================================================================================== #
@ -23,6 +28,9 @@ option(ZYAN_NO_LIBC
option(ZYAN_DEV_MODE
"Enable developer mode (-Wall, -Werror, ...)"
OFF)
option(ZYAN_FORCE_ASSERTS
"Forces asserts in release builds."
OFF)
# Build configuration
option(ZYCORE_BUILD_SHARED_LIB
@ -35,81 +43,70 @@ option(ZYCORE_BUILD_TESTS
"Build tests"
OFF)
# =============================================================================================== #
# Forced assertions hack #
# =============================================================================================== #
# The code for this is adapted from how LLVM forces asserts.
if (ZYAN_FORCE_ASSERTS)
set(vars
CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS_MINSIZEREL
CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_C_FLAGS_MINSIZEREL)
foreach (var ${vars})
string (REGEX REPLACE "(^| )[/-]D *NDEBUG($| )" " " "${var}" "${${var}}")
set("${var}" "${${var}} -UNDEBUG" CACHE STRING "" FORCE)
endforeach()
endif ()
# =============================================================================================== #
# GoogleTest #
# =============================================================================================== #
# Download and unpack googletest
# Search for GoogleTest, and fallback to downloading it if not found
if (ZYCORE_BUILD_TESTS)
if (NOT DEFINED ZYCORE_DOWNLOADED_GTEST)
configure_file("CMakeLists.txt.in" "${CMAKE_BINARY_DIR}/gtest/download/CMakeLists.txt")
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
RESULT_VARIABLE result
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/gtest/download")
if (result)
message(FATAL_ERROR "CMake step for googletest failed: ${result}")
endif()
execute_process(COMMAND ${CMAKE_COMMAND} --build .
RESULT_VARIABLE result
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/gtest/download")
if (result)
message(FATAL_ERROR "Build step for googletest failed: ${result}")
endif()
find_package(GTest QUIET)
if (GTest_FOUND)
# CMake 3.20 and upstream GTestConfig.cmake
if (TARGET GTest::gtest)
add_library(gtest ALIAS GTest::gtest)
# Older FindGTest
else ()
add_library(gtest ALIAS GTest::GTest)
endif ()
else ()
if (NOT DEFINED ZYCORE_DOWNLOADED_GTEST)
configure_file("CMakeLists.txt.in" "${CMAKE_BINARY_DIR}/gtest/download/CMakeLists.txt")
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
RESULT_VARIABLE result
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/gtest/download")
if (result)
message(FATAL_ERROR "CMake step for googletest failed: ${result}")
endif()
execute_process(COMMAND ${CMAKE_COMMAND} --build .
RESULT_VARIABLE result
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/gtest/download")
if (result)
message(FATAL_ERROR "Build step for googletest failed: ${result}")
endif()
set(ZYCORE_DOWNLOADED_GTEST TRUE CACHE BOOL "")
mark_as_advanced(ZYCORE_DOWNLOADED_GTEST)
endif ()
set(ZYCORE_DOWNLOADED_GTEST TRUE CACHE BOOL "")
mark_as_advanced(ZYCORE_DOWNLOADED_GTEST)
endif ()
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
add_subdirectory("${CMAKE_BINARY_DIR}/gtest/src" "${CMAKE_BINARY_DIR}/gtest/build"
EXCLUDE_FROM_ALL)
endif ()
endif ()
# =============================================================================================== #
# Exported functions #
# =============================================================================================== #
function (zyan_set_common_flags target)
if (NOT MSVC)
target_compile_options("${target}" PRIVATE "-std=c99")
endif ()
if (ZYAN_DEV_MODE)
# If in developer mode, be pedantic.
if (MSVC)
target_compile_options("${target}" PUBLIC "/WX" "/W4")
else ()
target_compile_options("${target}" PUBLIC "-Wall" "-pedantic" "-Wextra" "-Werror")
endif ()
endif ()
endfunction ()
function (zyan_set_source_group target)
if (ZYAN_DEV_MODE)
if (((CMAKE_MAJOR_VERSION GREATER 3) OR (CMAKE_MAJOR_VERSION EQUAL 3)) AND
((CMAKE_MINOR_VERSION GREATER 8) OR (CMAKE_MINOR_VERSION EQUAL 8)))
# Mirror directory structure in project files
get_property("TARGET_SOURCE_FILES" TARGET "${target}" PROPERTY SOURCES)
source_group(TREE "${CMAKE_CURRENT_LIST_DIR}" FILES ${TARGET_SOURCE_FILES})
endif ()
endif ()
endfunction ()
function (zyan_maybe_enable_wpo target)
if (ZYAN_WHOLE_PROGRAM_OPTIMIZATION AND MSVC)
set_target_properties("${target}" PROPERTIES COMPILE_FLAGS "/GL")
set_target_properties("${target}" PROPERTIES LINK_FLAGS_RELEASE "/LTCG")
endif ()
endfunction ()
function (zyan_maybe_enable_wpo_for_lib target)
if (ZYAN_WHOLE_PROGRAM_OPTIMIZATION AND MSVC)
set_target_properties("${target}" PROPERTIES COMPILE_FLAGS "/GL")
set_target_properties("${target}" PROPERTIES LINK_FLAGS_RELEASE "/LTCG")
set_target_properties("${target}" PROPERTIES STATIC_LIBRARY_FLAGS_RELEASE "/LTCG")
endif ()
endfunction ()
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
include(zyan-functions)
# =============================================================================================== #
# Library configuration #
@ -119,16 +116,23 @@ if (ZYCORE_BUILD_SHARED_LIB)
add_library("Zycore" SHARED)
else ()
add_library("Zycore" STATIC)
target_compile_definitions("Zycore" PUBLIC "ZYCORE_STATIC_BUILD")
endif ()
set_target_properties("Zycore" PROPERTIES LINKER_LANGUAGE C)
set_target_properties("Zycore" PROPERTIES
LINKER_LANGUAGE C
VERSION "${Zycore_VERSION}"
SOVERSION "${Zycore_VERSION_MAJOR}.${Zycore_VERSION_MINOR}"
DEFINE_SYMBOL "ZYCORE_SHOULD_EXPORT")
target_include_directories("Zycore"
PUBLIC "include" ${PROJECT_BINARY_DIR}
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<BUILD_INTERFACE:${PROJECT_BINARY_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
PRIVATE "src")
target_compile_definitions("Zycore" PRIVATE "_CRT_SECURE_NO_WARNINGS" "ZYCORE_EXPORTS")
target_compile_definitions("Zycore" PRIVATE "_CRT_SECURE_NO_WARNINGS")
zyan_set_common_flags("Zycore")
zyan_maybe_enable_wpo_for_lib("Zycore")
generate_export_header("Zycore" BASE_NAME "ZYCORE" EXPORT_FILE_NAME "ZycoreExportConfig.h")
zyan_maybe_enable_wpo("Zycore")
if (ZYAN_NO_LIBC)
target_compile_definitions("Zycore" PUBLIC "ZYAN_NO_LIBC")
@ -148,6 +152,7 @@ target_sources("Zycore"
# Common
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/Allocator.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/ArgParse.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/Atomic.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/Bitset.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/Comparison.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/Defines.h"
@ -160,6 +165,14 @@ target_sources("Zycore"
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/Types.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/Vector.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/Zycore.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/Internal/AtomicGNU.h"
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/Internal/AtomicMSVC.h"
# API
"src/API/Memory.c"
"src/API/Process.c"
"src/API/Synchronization.c"
"src/API/Terminal.c"
"src/API/Thread.c"
# Common
"src/Allocator.c"
"src/ArgParse.c"
@ -170,17 +183,6 @@ target_sources("Zycore"
"src/Vector.c"
"src/Zycore.c")
if (NOT ZYAN_NO_LIBC)
target_sources("Zycore"
PRIVATE
# API
"src/API/Memory.c"
"src/API/Process.c"
"src/API/Synchronization.c"
"src/API/Terminal.c"
"src/API/Thread.c")
endif ()
if (ZYCORE_BUILD_SHARED_LIB AND WIN32)
target_sources("Zycore" PRIVATE "resources/VersionInfo.rc")
endif ()
@ -189,28 +191,51 @@ zyan_set_source_group("Zycore")
if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" AND NOT ZYAN_NO_LIBC)
target_compile_definitions("Zycore" PRIVATE "_GNU_SOURCE")
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
target_link_libraries("Zycore" Threads::Threads)
endif ()
configure_package_config_file(cmake/zycore-config.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/zycore-config.cmake"
INSTALL_DESTINATION "${CMAKE_INSTALL_PREFIX}/cmake"
INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/zycore"
)
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/zycore-config-version.cmake"
COMPATIBILITY SameMajorVersion
)
install(FILES
"cmake/zyan-functions.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/zycore-config.cmake"
DESTINATION "${CMAKE_INSTALL_PREFIX}/cmake"
"${CMAKE_CURRENT_BINARY_DIR}/zycore-config-version.cmake"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/zycore"
)
install(TARGETS "Zycore"
install(TARGETS "Zycore" EXPORT "zycore-targets"
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
install(FILES
"${PROJECT_BINARY_DIR}/ZycoreExportConfig.h"
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
install(EXPORT "zycore-targets"
NAMESPACE "Zycore::"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/zycore")
install(DIRECTORY "include/" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
# =============================================================================================== #
# Doxygen documentation #
# =============================================================================================== #
find_package(Doxygen)
if (DOXYGEN_FOUND)
doxygen_add_docs(ZycoreDoc "include/Zycore/" ALL)
install(
DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/html/"
DESTINATION "${CMAKE_INSTALL_DOCDIR}/api"
COMPONENT Documentation
)
endif()
# =============================================================================================== #
# Developer mode #
# =============================================================================================== #
@ -245,19 +270,22 @@ endif ()
function (zyan_add_test test)
add_executable("Test${test}" "tests/${test}.cpp")
if (NOT MSVC)
target_compile_options("Test${test}" PRIVATE "-std=c++17")
endif ()
target_link_libraries("Test${test}" "Zycore")
target_link_libraries("Test${test}" "gtest")
set_target_properties("Test${test}" PROPERTIES FOLDER "Tests")
target_link_libraries("Test${test}" "Zycore" "gtest")
set_target_properties("Test${test}" PROPERTIES
LANGUAGE CXX
CXX_STANDARD 17
CXX_EXTENSIONS OFF
CXX_STANDARD_REQUIRED ON
FOLDER "Tests"
)
target_compile_definitions("Test${test}" PRIVATE "_CRT_SECURE_NO_WARNINGS")
zyan_maybe_enable_wpo("Test${test}")
add_test("${test}" "Test${test}")
endfunction ()
if (ZYCORE_BUILD_TESTS)
enable_language(CXX)
enable_testing()
zyan_add_test("String")
zyan_add_test("Vector")
zyan_add_test("ArgParse")

View file

@ -1,5 +1,9 @@
# Zyan Core Library for C
<a href="./LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="License: MIT"></a>
<a href="https://github.com/zyantific/zycore-c/actions"><img src="https://github.com/zyantific/zycore-c/workflows/GitHub%20Actions%20CI/badge.svg" alt="GitHub Actions"></a>
<a href="https://discord.zyantific.com/"><img src="https://img.shields.io/discord/390136917779415060.svg?logo=discord&label=Discord" alt="Discord"></a>
Internal library providing platform independent types, macros and a fallback for environments without LibC.
## Features

View file

@ -0,0 +1,45 @@
# =============================================================================================== #
# Exported functions #
# =============================================================================================== #
function (zyan_set_common_flags target)
if (MSVC)
# MSVC support for C11 is still pretty lacking, so we instead just disable the warnings
# about using non-standard C extensions.
target_compile_options("${target}" PUBLIC "/wd4201")
else ()
# For the more civilized compilers, we go with C11.
set_target_properties("${target}" PROPERTIES C_STANDARD 11)
endif ()
if (ZYAN_DEV_MODE)
# If in developer mode, be pedantic.
if (MSVC)
target_compile_options("${target}" PUBLIC "/WX" "/W4")
else ()
target_compile_options("${target}" PUBLIC "-Wall" "-pedantic" "-Wextra" "-Werror")
endif ()
endif ()
endfunction ()
function (zyan_set_source_group target)
if (ZYAN_DEV_MODE)
if (((CMAKE_MAJOR_VERSION GREATER 3) OR (CMAKE_MAJOR_VERSION EQUAL 3)) AND
((CMAKE_MINOR_VERSION GREATER 8) OR (CMAKE_MINOR_VERSION EQUAL 8)))
# Mirror directory structure in project files
get_property("TARGET_SOURCE_FILES" TARGET "${target}" PROPERTY SOURCES)
source_group(TREE "${CMAKE_CURRENT_LIST_DIR}" FILES ${TARGET_SOURCE_FILES})
endif ()
endif ()
endfunction ()
function (zyan_maybe_enable_wpo target)
if (ZYAN_WHOLE_PROGRAM_OPTIMIZATION)
set_property(TARGET "${target}" PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
endif ()
endfunction ()
# deprecated alias for `zyan_maybe_enable_wpo`, for backward compatibility.
function (zyan_maybe_enable_wpo_for_lib target)
zyan_maybe_enable_wpo("${target}")
endfunction ()

View file

@ -2,6 +2,15 @@ set(zycore_VERSION @PROJECT_VERSION@)
@PACKAGE_INIT@
include(CMakeFindDependencyMacro)
if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" AND NOT @ZYAN_NO_LIBC@)
find_dependency(Threads)
endif()
include("${CMAKE_CURRENT_LIST_DIR}/zyan-functions.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/zycore-targets.cmake")
set_and_check(zycore_INCLUDE_DIR "${PACKAGE_PREFIX_DIR}/@CMAKE_INSTALL_INCLUDEDIR@")
set_and_check(zycore_LIB_DIR "${PACKAGE_PREFIX_DIR}/@CMAKE_INSTALL_LIBDIR@")

View file

@ -98,6 +98,7 @@ static ZyanStatus PerformBasicTests(ZyanVector* vector)
{
InitTestdata(&e_v, i);
ZYAN_CHECK(ZyanVectorPushBack(vector, &e_v));
printf("i=%d cap=%" PRIuPTR, i, vector->capacity);
}
// Remove elements `#05..#09`
@ -332,7 +333,7 @@ static ZyanStatus TestAllocator(void)
// dynamic shrinking is disabled
ZyanVector vector;
ZYAN_CHECK(ZyanVectorInitEx(&vector, sizeof(TestStruct), 5, ZYAN_NULL, &allocator,
10.0f, 0.0f));
10, 0));
static TestStruct e_v;

View file

@ -32,11 +32,12 @@
#ifndef ZYCORE_API_MEMORY_H
#define ZYCORE_API_MEMORY_H
#include <ZycoreExportConfig.h>
#include <Zycore/Defines.h>
#include <Zycore/Status.h>
#include <Zycore/Types.h>
#ifndef ZYAN_NO_LIBC
#if defined(ZYAN_WINDOWS)
# include <windows.h>
#elif defined(ZYAN_POSIX)
@ -131,4 +132,6 @@ ZYCORE_EXPORT ZyanStatus ZyanMemoryVirtualFree(void* address, ZyanUSize size);
/* ============================================================================================== */
#endif /* ZYAN_NO_LIBC */
#endif /* ZYCORE_API_MEMORY_H */

View file

@ -32,10 +32,11 @@
#ifndef ZYCORE_API_PROCESS_H
#define ZYCORE_API_PROCESS_H
#include <ZycoreExportConfig.h>
#include <Zycore/Status.h>
#include <Zycore/Types.h>
#ifndef ZYAN_NO_LIBC
/* ============================================================================================== */
/* Enums and types */
/* ============================================================================================== */
@ -64,4 +65,6 @@ ZYCORE_EXPORT ZyanStatus ZyanProcessFlushInstructionCache(void* address, ZyanUSi
/* ============================================================================================== */
#endif /* ZYAN_NO_LIBC */
#endif /* ZYCORE_API_PROCESS_H */

View file

@ -32,12 +32,11 @@
#ifndef ZYCORE_API_SYNCHRONIZATION_H
#define ZYCORE_API_SYNCHRONIZATION_H
#ifndef ZYAN_NO_LIBC
#include <ZycoreExportConfig.h>
#include <Zycore/Defines.h>
#include <Zycore/Status.h>
#ifndef ZYAN_NO_LIBC
#ifdef __cplusplus
extern "C" {
#endif

View file

@ -32,7 +32,6 @@
#ifndef ZYCORE_API_TERMINAL_H
#define ZYCORE_API_TERMINAL_H
#include <ZycoreExportConfig.h>
#include <Zycore/LibC.h>
#include <Zycore/Status.h>

View file

@ -32,12 +32,11 @@
#ifndef ZYCORE_API_THREAD_H
#define ZYCORE_API_THREAD_H
#ifndef ZYAN_NO_LIBC
#include <ZycoreExportConfig.h>
#include <Zycore/Defines.h>
#include <Zycore/Status.h>
#ifndef ZYAN_NO_LIBC
#ifdef __cplusplus
extern "C" {
#endif

View file

@ -32,7 +32,6 @@
#ifndef ZYCORE_ALLOCATOR_H
#define ZYCORE_ALLOCATOR_H
#include <ZycoreExportConfig.h>
#include <Zycore/Status.h>
#include <Zycore/Types.h>

236
include/Zycore/Atomic.h Normal file
View file

@ -0,0 +1,236 @@
/***************************************************************************************************
Zyan Core Library (Zyan-C)
Original Author : Florian Bernd
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
***************************************************************************************************/
/**
* @file
* Cross compiler atomic intrinsics.
*/
#ifndef ZYCORE_ATOMIC_H
#define ZYCORE_ATOMIC_H
#ifdef __cplusplus
extern "C" {
#endif
#include <Zycore/Defines.h>
#include <Zycore/Types.h>
/* ============================================================================================== */
/* Enums and Types */
/* ============================================================================================== */
/*
* Wraps a 32-bit value to provide atomic access.
*/
typedef struct ZyanAtomic32_
{
ZyanU32 volatile value;
} ZyanAtomic32;
/*
* Wraps a 64-bit value to provide atomic access.
*/
typedef struct ZyanAtomic64_
{
ZyanU64 volatile value;
} ZyanAtomic64;
/*
* Wraps a pointer-sized value to provide atomic access.
*/
typedef struct ZyanAtomicPointer_
{
ZyanVoidPointer volatile value;
} ZyanAtomicPointer;
/* ============================================================================================== */
/* Macros */
/* ============================================================================================== */
/* ---------------------------------------------------------------------------------------------- */
/* Pointer sized */
/* ---------------------------------------------------------------------------------------------- */
/**
* @copydoc ZyanAtomicCompareExchange
*/
#define ZYAN_ATOMIC_COMPARE_EXCHANGE(destination, comparand, value) \
ZyanAtomicCompareExchange((ZyanAtomicPointer*)&(destination), (comparand), (value))
/**
* @copydoc ZyanAtomicIncrement
*/
#define ZYAN_ATOMIC_INCREMENT(destination) \
ZyanAtomicIncrement((ZyanAtomicPointer*)&(destination));
/**
* @copydoc ZyanAtomicDecrement
*/
#define ZYAN_ATOMIC_DECREMENT(destination) \
ZyanAtomicDecrement((ZyanAtomicPointer*)&(destination));
/* ---------------------------------------------------------------------------------------------- */
/* 32-bit */
/* ---------------------------------------------------------------------------------------------- */
/**
* @copydoc ZyanAtomicCompareExchange
*/
#define ZYAN_ATOMIC_COMPARE_EXCHANGE32(destination, comparand, value) \
ZyanAtomicCompareExchange32((ZyanAtomic32*)&(destination), (comparand), (value))
/**
* @copydoc ZyanAtomicIncrement
*/
#define ZYAN_ATOMIC_INCREMENT32(destination) \
ZyanAtomicIncrement32((ZyanAtomic32*)&(destination));
/**
* @copydoc ZyanAtomicDecrement
*/
#define ZYAN_ATOMIC_DECREMENT32(destination) \
ZyanAtomicDecrement32((ZyanAtomic32*)&(destination));
/* ---------------------------------------------------------------------------------------------- */
/* 64-bit */
/* ---------------------------------------------------------------------------------------------- */
/**
* @copydoc ZyanAtomicCompareExchange
*/
#define ZYAN_ATOMIC_COMPARE_EXCHANGE64(destination, comparand, value) \
ZyanAtomicCompareExchange64((ZyanAtomic64*)&(destination), (comparand), (value))
/**
* @copydoc ZyanAtomicIncrement
*/
#define ZYAN_ATOMIC_INCREMENT64(destination) \
ZyanAtomicIncrement64((ZyanAtomic64*)&(destination));
/**
* @copydoc ZyanAtomicDecrement
*/
#define ZYAN_ATOMIC_DECREMENT64(destination) \
ZyanAtomicDecrement64((ZyanAtomic64*)&(destination));
/* ---------------------------------------------------------------------------------------------- */
/* ============================================================================================== */
/* Functions */
/* ============================================================================================== */
/* ---------------------------------------------------------------------------------------------- */
/* Pointer sized */
/* ---------------------------------------------------------------------------------------------- */
/**
* Compares two values for equality and, if they are equal, replaces the first value.
*
* @param destination A pointer to the destination value.
* @param comparand The value to compare with.
* @param value The replacement value.
*
* @return The original value.
*/
static ZyanUPointer ZyanAtomicCompareExchange(ZyanAtomicPointer* destination,
ZyanUPointer comparand, ZyanUPointer value);
/**
* Increments the given value and stores the result, as an atomic operation.
*
* @param destination A pointer to the destination value.
*
* @return The incremented value.
*/
static ZyanUPointer ZyanAtomicIncrement(ZyanAtomicPointer* destination);
/**
* Decrements the given value and stores the result, as an atomic operation.
*
* @param destination A pointer to the destination value.
*
* @return The decremented value.
*/
static ZyanUPointer ZyanAtomicDecrement(ZyanAtomicPointer* destination);
/* ---------------------------------------------------------------------------------------------- */
/* 32-bit */
/* ---------------------------------------------------------------------------------------------- */
/**
* @copydoc ZyanAtomicCompareExchange
*/
static ZyanU32 ZyanAtomicCompareExchange32(ZyanAtomic32* destination,
ZyanU32 comparand, ZyanU32 value);
/**
* @copydoc ZyanAtomicIncrement
*/
static ZyanU32 ZyanAtomicIncrement32(ZyanAtomic32* destination);
/**
* @copydoc ZyanAtomicDecrement
*/
static ZyanU32 ZyanAtomicDecrement32(ZyanAtomic32* destination);
/* ---------------------------------------------------------------------------------------------- */
/* 64-bit */
/* ---------------------------------------------------------------------------------------------- */
/**
* @copydoc ZyanAtomicCompareExchange
*/
static ZyanU64 ZyanAtomicCompareExchange64(ZyanAtomic64* destination,
ZyanU64 comparand, ZyanU64 value);
/**
* @copydoc ZyanAtomicIncrement
*/
static ZyanU64 ZyanAtomicIncrement64(ZyanAtomic64* destination);
/**
* @copydoc ZyanAtomicDecrement
*/
static ZyanU64 ZyanAtomicDecrement64(ZyanAtomic64* destination);
/* ---------------------------------------------------------------------------------------------- */
/* ============================================================================================== */
#if defined(ZYAN_CLANG) || defined(ZYAN_GCC) || defined(ZYAN_ICC)
# include <Zycore/Internal/AtomicGNU.h>
#elif defined(ZYAN_MSVC)
# include <Zycore/Internal/AtomicMSVC.h>
#else
# error "Unsupported compiler detected"
#endif
#ifdef __cplusplus
}
#endif
#endif /* ZYCORE_ATOMIC_H */

View file

@ -32,7 +32,6 @@
#ifndef ZYCORE_BITSET_H
#define ZYCORE_BITSET_H
#include <ZycoreExportConfig.h>
#include <Zycore/Allocator.h>
#include <Zycore/Status.h>
#include <Zycore/Types.h>
@ -96,7 +95,7 @@ typedef ZyanStatus (*ZyanBitsetByteOperation)(ZyanU8* v1, const ZyanU8* v2);
* @return A zyan status code.
*
* The space for the bitset is dynamically allocated by the default allocator using the default
* growth factor of `2.0f` and the default shrink threshold of `0.5f`.
* growth factor and the default shrink threshold.
*/
ZYCORE_EXPORT ZYAN_REQUIRES_LIBC ZyanStatus ZyanBitsetInit(ZyanBitset* bitset, ZyanUSize count);
@ -109,16 +108,16 @@ ZYCORE_EXPORT ZYAN_REQUIRES_LIBC ZyanStatus ZyanBitsetInit(ZyanBitset* bitset, Z
* @param bitset A pointer to the `ZyanBitset` instance.
* @param count The initial amount of bits.
* @param allocator A pointer to a `ZyanAllocator` instance.
* @param growth_factor The growth factor (from `1.0f` to `x.xf`).
* @param shrink_threshold The shrink threshold (from `0.0f` to `1.0f`).
* @param growth_factor The growth factor.
* @param shrink_threshold The shrink threshold.
*
* @return A zyan status code.
*
* A growth factor of `1.0f` disables overallocation and a shrink threshold of `0.0f` disables
* A growth factor of `1` disables overallocation and a shrink threshold of `0` disables
* dynamic shrinking.
*/
ZYCORE_EXPORT ZyanStatus ZyanBitsetInitEx(ZyanBitset* bitset, ZyanUSize count,
ZyanAllocator* allocator, float growth_factor, float shrink_threshold);
ZyanAllocator* allocator, ZyanU8 growth_factor, ZyanU8 shrink_threshold);
/**
* Initializes the given `ZyanBitset` instance and configures it to use a custom user
@ -266,7 +265,7 @@ ZYCORE_EXPORT ZyanStatus ZyanBitsetToggle(ZyanBitset* bitset, ZyanUSize index);
* @param index The bit index.
*
* @return `ZYAN_STATUS_TRUE`, if the bit is set or `ZYAN_STATUS_FALSE`, if not, Another zyan
* status code, if an error occured.
* status code, if an error occurred.
*/
ZYCORE_EXPORT ZyanStatus ZyanBitsetTest(ZyanBitset* bitset, ZyanUSize index);
@ -276,7 +275,7 @@ ZYCORE_EXPORT ZyanStatus ZyanBitsetTest(ZyanBitset* bitset, ZyanUSize index);
* @param bitset A pointer to the `ZyanBitset` instance.
*
* @return `ZYAN_STATUS_TRUE`, if the bit is set or `ZYAN_STATUS_FALSE`, if not. Another zyan
* status code, if an error occured.
* status code, if an error occurred.
*/
ZYCORE_EXPORT ZyanStatus ZyanBitsetTestMSB(ZyanBitset* bitset);
@ -286,7 +285,7 @@ ZYCORE_EXPORT ZyanStatus ZyanBitsetTestMSB(ZyanBitset* bitset);
* @param bitset A pointer to the `ZyanBitset` instance.
*
* @return `ZYAN_STATUS_TRUE`, if the bit is set or `ZYAN_STATUS_FALSE`, if not. Another zyan
* status code, if an error occured.
* status code, if an error occurred.
*/
ZYCORE_EXPORT ZyanStatus ZyanBitsetTestLSB(ZyanBitset* bitset);
@ -427,7 +426,7 @@ ZYCORE_EXPORT ZyanStatus ZyanBitsetCount(const ZyanBitset* bitset, ZyanUSize* co
* @param bitset A pointer to the `ZyanBitset` instance.
*
* @return `ZYAN_STATUS_TRUE`, if all bits are set, `ZYAN_STATUS_FALSE`, if not. Another zyan
* status code, if an error occured.
* status code, if an error occurred.
*/
ZYCORE_EXPORT ZyanStatus ZyanBitsetAll(const ZyanBitset* bitset);
@ -437,7 +436,7 @@ ZYCORE_EXPORT ZyanStatus ZyanBitsetAll(const ZyanBitset* bitset);
* @param bitset A pointer to the `ZyanBitset` instance.
*
* @return `ZYAN_STATUS_TRUE`, if at least one bit is set, `ZYAN_STATUS_FALSE`, if not. Another
* zyan status code, if an error occured.
* zyan status code, if an error occurred.
*/
ZYCORE_EXPORT ZyanStatus ZyanBitsetAny(const ZyanBitset* bitset);
@ -447,7 +446,7 @@ ZYCORE_EXPORT ZyanStatus ZyanBitsetAny(const ZyanBitset* bitset);
* @param bitset A pointer to the `ZyanBitset` instance.
*
* @return `ZYAN_STATUS_TRUE`, if none bits are set, `ZYAN_STATUS_FALSE`, if not. Another zyan
* status code, if an error occured.
* status code, if an error occurred.
*/
ZYCORE_EXPORT ZyanStatus ZyanBitsetNone(const ZyanBitset* bitset);

View file

@ -85,6 +85,9 @@
# define ZYAN_WINDOWS
#elif defined(__EMSCRIPTEN__)
# define ZYAN_EMSCRIPTEN
#elif defined(__wasi__) || defined(__WASI__)
// via: https://reviews.llvm.org/D57155
# define ZYAN_WASI
#elif defined(__APPLE__)
# define ZYAN_APPLE
# define ZYAN_POSIX
@ -131,8 +134,14 @@
# define ZYAN_AARCH64
#elif defined(_M_ARM) || defined(_M_ARMT) || defined(__arm__) || defined(__thumb__)
# define ZYAN_ARM
#elif defined(__EMSCRIPTEN__)
// Nothing to do, `ZYAN_EMSCRIPTEN` is both platform and arch macro for this one.
#elif defined(__EMSCRIPTEN__) || defined(__wasm__) || defined(__WASM__)
# define ZYAN_WASM
#elif defined(__powerpc64__)
# define ZYAN_PPC64
#elif defined(__powerpc__)
# define ZYAN_PPC
#elif defined(__riscv) && __riscv_xlen == 64
# define ZYAN_RISCV64
#else
# error "Unsupported architecture detected"
#endif
@ -157,6 +166,73 @@
# define ZYAN_RELEASE
#endif
/* ============================================================================================== */
/* Deprecation hint */
/* ============================================================================================== */
#if defined(ZYAN_GCC) || defined(ZYAN_CLANG)
# define ZYAN_DEPRECATED __attribute__((__deprecated__))
#elif defined(ZYAN_MSVC)
# define ZYAN_DEPRECATED __declspec(deprecated)
#else
# define ZYAN_DEPRECATED
#endif
/* ============================================================================================== */
/* Generic DLL import/export helpers */
/* ============================================================================================== */
#if defined(ZYAN_MSVC)
# define ZYAN_DLLEXPORT __declspec(dllexport)
# define ZYAN_DLLIMPORT __declspec(dllimport)
#else
# define ZYAN_DLLEXPORT
# define ZYAN_DLLIMPORT
#endif
/* ============================================================================================== */
/* Zycore dll{export,import} */
/* ============================================================================================== */
// This is a cut-down version of what CMake's `GenerateExportHeader` would usually generate. To
// simplify builds without CMake, we define these things manually instead of relying on CMake
// to generate the header.
//
// For static builds, our CMakeList will define `ZYCORE_STATIC_BUILD`. For shared library builds,
// our CMake will define `ZYCORE_SHOULD_EXPORT` depending on whether the target is being imported or
// exported. If CMake isn't used, users can manually define these to fit their use-case.
// Backward compatibility: CMake would previously generate these variables names. However, because
// they have pretty cryptic names, we renamed them when we got rid of `GenerateExportHeader`. For
// backward compatibility for users that don't use CMake and previously manually defined these, we
// translate the old defines here and print a warning.
#if defined(ZYCORE_STATIC_DEFINE)
# pragma message("ZYCORE_STATIC_DEFINE was renamed to ZYCORE_STATIC_BUILD.")
# define ZYCORE_STATIC_BUILD
#endif
#if defined(Zycore_EXPORTS)
# pragma message("Zycore_EXPORTS was renamed to ZYCORE_SHOULD_EXPORT.")
# define ZYCORE_SHOULD_EXPORT
#endif
/**
* Symbol is exported in shared library builds.
*/
#if defined(ZYCORE_STATIC_BUILD)
# define ZYCORE_EXPORT
#else
# if defined(ZYCORE_SHOULD_EXPORT)
# define ZYCORE_EXPORT ZYAN_DLLEXPORT
# else
# define ZYCORE_EXPORT ZYAN_DLLIMPORT
# endif
#endif
/**
* Symbol is not exported and for internal use only.
*/
#define ZYCORE_NO_EXPORT
/* ============================================================================================== */
/* Misc compatibility macros */
/* ============================================================================================== */
@ -173,6 +249,14 @@
# define ZYAN_INLINE static inline
#endif
#if defined(ZYAN_MSVC)
# define ZYAN_NOINLINE __declspec(noinline)
#elif defined(ZYAN_GCC) || defined(ZYAN_CLANG)
# define ZYAN_NOINLINE __attribute__((noinline))
#else
# define ZYAN_NOINLINE
#endif
/* ============================================================================================== */
/* Debugging and optimization macros */
/* ============================================================================================== */
@ -193,7 +277,7 @@
/**
* Compiler-time assertion.
*/
#if __STDC_VERSION__ >= 201112L && !defined(__cplusplus)
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L && !defined(__cplusplus)
# define ZYAN_STATIC_ASSERT(x) _Static_assert(x, #x)
#elif (defined(__cplusplus) && __cplusplus >= 201103L) || \
(defined(__cplusplus) && defined (_MSC_VER) && (_MSC_VER >= 1600)) || \
@ -256,7 +340,7 @@
* Intentional fallthrough.
*/
#if defined(ZYAN_GCC) && __GNUC__ >= 7
# define ZYAN_FALLTHROUGH __attribute__((fallthrough))
# define ZYAN_FALLTHROUGH ; __attribute__((__fallthrough__))
#else
# define ZYAN_FALLTHROUGH
#endif

View file

@ -32,7 +32,6 @@
#ifndef ZYCORE_FORMAT_H
#define ZYCORE_FORMAT_H
#include <ZycoreExportConfig.h>
#include <Zycore/Status.h>
#include <Zycore/String.h>
#include <Zycore/Types.h>

View file

@ -0,0 +1,117 @@
/***************************************************************************************************
Zyan Core Library (Zyan-C)
Original Author : Florian Bernd
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
***************************************************************************************************/
#ifndef ZYCORE_ATOMIC_GNU_H
#define ZYCORE_ATOMIC_GNU_H
#ifdef __cplusplus
extern "C" {
#endif
#include <Zycore/Defines.h>
#include <Zycore/Types.h>
/* ============================================================================================== */
/* Functions */
/* ============================================================================================== */
#if defined(ZYAN_CLANG) || defined(ZYAN_GCC) || defined(ZYAN_ICC)
/* ---------------------------------------------------------------------------------------------- */
/* Pointer sized */
/* ---------------------------------------------------------------------------------------------- */
ZYAN_INLINE ZyanUPointer ZyanAtomicCompareExchange(ZyanAtomicPointer* destination,
ZyanUPointer comparand, ZyanUPointer value)
{
return (ZyanUPointer)(__sync_val_compare_and_swap(
&destination->value, (void*)comparand, (void*)value, &destination->value));
}
ZYAN_INLINE ZyanUPointer ZyanAtomicIncrement(ZyanAtomicPointer* destination)
{
return (ZyanUPointer)(__sync_fetch_and_add(&destination->value, (void*)1,
&destination->value)) + 1;
}
ZYAN_INLINE ZyanUPointer ZyanAtomicDecrement(ZyanAtomicPointer* destination)
{
return (ZyanUPointer)(__sync_sub_and_fetch(&destination->value, (void*)1, &destination->value));
}
/* ---------------------------------------------------------------------------------------------- */
/* 32-bit */
/* ---------------------------------------------------------------------------------------------- */
ZYAN_INLINE ZyanU32 ZyanAtomicCompareExchange32(ZyanAtomic32* destination,
ZyanU32 comparand, ZyanU32 value)
{
return (ZyanU32)(__sync_val_compare_and_swap(&destination->value, comparand, value,
&destination->value));
}
ZYAN_INLINE ZyanU32 ZyanAtomicIncrement32(ZyanAtomic32* destination)
{
return (ZyanU32)(__sync_fetch_and_add(&destination->value, 1, &destination->value)) + 1;
}
ZYAN_INLINE ZyanU32 ZyanAtomicDecrement32(ZyanAtomic32* destination)
{
return (ZyanU32)(__sync_sub_and_fetch(&destination->value, 1, &destination->value));
}
/* ---------------------------------------------------------------------------------------------- */
/* 64-bit */
/* ---------------------------------------------------------------------------------------------- */
ZYAN_INLINE ZyanU64 ZyanAtomicCompareExchange64(ZyanAtomic64* destination,
ZyanU64 comparand, ZyanU64 value)
{
return (ZyanU64)(__sync_val_compare_and_swap(&destination->value, comparand, value,
&destination->value));
}
ZYAN_INLINE ZyanU64 ZyanAtomicIncrement64(ZyanAtomic64* destination)
{
return (ZyanU64)(__sync_fetch_and_add(&destination->value, 1, &destination->value)) + 1;
}
ZYAN_INLINE ZyanU64 ZyanAtomicDecrement64(ZyanAtomic64* destination)
{
return (ZyanU64)(__sync_sub_and_fetch(&destination->value, 1, &destination->value));
}
/* ---------------------------------------------------------------------------------------------- */
#endif
/* ============================================================================================== */
#ifdef __cplusplus
}
#endif
#endif /* ZYCORE_ATOMIC_GNU_H */

View file

@ -0,0 +1,141 @@
/***************************************************************************************************
Zyan Core Library (Zyan-C)
Original Author : Florian Bernd
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
***************************************************************************************************/
#ifndef ZYCORE_ATOMIC_MSVC_H
#define ZYCORE_ATOMIC_MSVC_H
#ifdef __cplusplus
extern "C" {
#endif
#include <Windows.h>
#include <Zycore/Defines.h>
#include <Zycore/Types.h>
/* ============================================================================================== */
/* Functions */
/* ============================================================================================== */
#if defined(ZYAN_MSVC)
/* ---------------------------------------------------------------------------------------------- */
/* Pointer sized */
/* ---------------------------------------------------------------------------------------------- */
#if defined(ZYAN_X86)
static ZYAN_INLINE ZyanUPointer ZyanAtomicCompareExchange(ZyanAtomicPointer* destination,
ZyanUPointer comparand, ZyanUPointer value)
{
return (ZyanUPointer)ZyanAtomicCompareExchange32((ZyanAtomic32*)destination, comparand, value);
}
static ZYAN_INLINE ZyanUPointer ZyanAtomicIncrement(ZyanAtomicPointer* destination)
{
return (ZyanUPointer)ZyanAtomicIncrement32((ZyanAtomic32*)destination);
}
static ZYAN_INLINE ZyanUPointer ZyanAtomicDecrement(ZyanAtomicPointer* destination)
{
return (ZyanUPointer)ZyanAtomicDecrement32((ZyanAtomic32*)destination);
}
#elif defined(ZYAN_X64)
static ZYAN_INLINE ZyanUPointer ZyanAtomicCompareExchange(ZyanAtomicPointer* destination,
ZyanUPointer comparand, ZyanUPointer value)
{
return (ZyanUPointer)ZyanAtomicCompareExchange64((ZyanAtomic64*)destination, comparand, value);
}
static ZYAN_INLINE ZyanUPointer ZyanAtomicIncrement(ZyanAtomicPointer* destination)
{
return (ZyanUPointer)ZyanAtomicIncrement64((ZyanAtomic64*)destination);
}
static ZYAN_INLINE ZyanUPointer ZyanAtomicDecrement(ZyanAtomicPointer* destination)
{
return (ZyanUPointer)ZyanAtomicDecrement64((ZyanAtomic64*)destination);
}
#else
# error "Unsupported architecture detected"
#endif
/* ---------------------------------------------------------------------------------------------- */
/* 32-bit */
/* ---------------------------------------------------------------------------------------------- */
static ZYAN_INLINE ZyanU32 ZyanAtomicCompareExchange32(ZyanAtomic32* destination,
ZyanU32 comparand, ZyanU32 value)
{
return (ZyanU32)(_InterlockedCompareExchange((volatile LONG*)&(destination->value),
(LONG)value, (LONG)comparand));
}
static ZYAN_INLINE ZyanU32 ZyanAtomicIncrement32(ZyanAtomic32* destination)
{
return (ZyanU32)(_InterlockedIncrement((volatile LONG*)&(destination->value)));
}
static ZYAN_INLINE ZyanU32 ZyanAtomicDecrement32(ZyanAtomic32* destination)
{
return (ZyanU32)(_InterlockedDecrement((volatile LONG*)&(destination->value)));
}
/* ---------------------------------------------------------------------------------------------- */
/* 64-bit */
/* ---------------------------------------------------------------------------------------------- */
static ZYAN_INLINE ZyanU64 ZyanAtomicCompareExchange64(ZyanAtomic64* destination,
ZyanU64 comparand, ZyanU64 value)
{
return (ZyanU64)(_InterlockedCompareExchange64((volatile LONG64*)&(destination->value),
(LONG64)value, (LONG64)comparand));
}
static ZYAN_INLINE ZyanU64 ZyanAtomicIncrement64(ZyanAtomic64* destination)
{
return (ZyanU64)(_InterlockedIncrement64((volatile LONG64*)&(destination->value)));
}
static ZYAN_INLINE ZyanU64 ZyanAtomicDecrement64(ZyanAtomic64* destination)
{
return (ZyanU64)(_InterlockedDecrement64((volatile LONG64*)&(destination->value)));
}
/* ---------------------------------------------------------------------------------------------- */
#endif
/* ============================================================================================== */
#ifdef __cplusplus
}
#endif
#endif /* ZYCORE_ATOMIC_MSVC_H */

View file

@ -32,7 +32,6 @@
#ifndef ZYCORE_LIST_H
#define ZYCORE_LIST_H
#include <ZycoreExportConfig.h>
#include <Zycore/Allocator.h>
#include <Zycore/Object.h>
#include <Zycore/Status.h>

View file

@ -32,7 +32,6 @@
#ifndef ZYCORE_STRING_H
#define ZYCORE_STRING_H
#include <ZycoreExportConfig.h>
#include <Zycore/Allocator.h>
#include <Zycore/Status.h>
#include <Zycore/Types.h>
@ -55,12 +54,12 @@ extern "C" {
/**
* The default growth factor for all string instances.
*/
#define ZYAN_STRING_DEFAULT_GROWTH_FACTOR 2.00f
#define ZYAN_STRING_DEFAULT_GROWTH_FACTOR 2
/**
* The default shrink threshold for all string instances.
*/
#define ZYAN_STRING_DEFAULT_SHRINK_THRESHOLD 0.25f
#define ZYAN_STRING_DEFAULT_SHRINK_THRESHOLD 4
/* ============================================================================================== */
/* Enums and types */
@ -71,7 +70,7 @@ extern "C" {
/* ---------------------------------------------------------------------------------------------- */
/**
* Defines the `ZyanStringFlags` datatype.
* Defines the `ZyanStringFlags` data-type.
*/
typedef ZyanU8 ZyanStringFlags;
@ -181,8 +180,8 @@ typedef struct ZyanStringView_
/* vector */ \
{ \
/* allocator */ ZYAN_NULL, \
/* growth_factor */ 1.0f, \
/* shrink_threshold */ 0.0f, \
/* growth_factor */ 1, \
/* shrink_threshold */ 0, \
/* size */ sizeof(string), \
/* capacity */ sizeof(string), \
/* element_size */ sizeof(char), \
@ -213,7 +212,7 @@ typedef struct ZyanStringView_
* @return A zyan status code.
*
* The memory for the string is dynamically allocated by the default allocator using the default
* growth factor of `2.0f` and the default shrink threshold of `0.25f`.
* growth factor and the default shrink threshold.
*
* The allocated buffer will be at least one character larger than the given `capacity`, to reserve
* space for the terminating '\0'.
@ -231,12 +230,12 @@ ZYCORE_EXPORT ZYAN_REQUIRES_LIBC ZyanStatus ZyanStringInit(ZyanString* string, Z
* @param string A pointer to the `ZyanString` instance.
* @param capacity The initial capacity (number of characters).
* @param allocator A pointer to a `ZyanAllocator` instance.
* @param growth_factor The growth factor (from `1.0f` to `x.xf`).
* @param shrink_threshold The shrink threshold (from `0.0f` to `1.0f`).
* @param growth_factor The growth factor.
* @param shrink_threshold The shrink threshold.
*
* @return A zyan status code.
*
* A growth factor of `1.0f` disables overallocation and a shrink threshold of `0.0f` disables
* A growth factor of `1` disables overallocation and a shrink threshold of `0` disables
* dynamic shrinking.
*
* The allocated buffer will be at least one character larger than the given `capacity`, to reserve
@ -245,7 +244,7 @@ ZYCORE_EXPORT ZYAN_REQUIRES_LIBC ZyanStatus ZyanStringInit(ZyanString* string, Z
* Finalization with `ZyanStringDestroy` is required for all strings created by this function.
*/
ZYCORE_EXPORT ZyanStatus ZyanStringInitEx(ZyanString* string, ZyanUSize capacity,
ZyanAllocator* allocator, float growth_factor, float shrink_threshold);
ZyanAllocator* allocator, ZyanU8 growth_factor, ZyanU8 shrink_threshold);
/**
* Initializes the given `ZyanString` instance and configures it to use a custom user
@ -295,7 +294,7 @@ ZYCORE_EXPORT ZyanStatus ZyanStringDestroy(ZyanString* string);
* string or `destination` points to an already initialized `ZyanString` instance.
*
* The memory for the string is dynamically allocated by the default allocator using the default
* growth factor of `2.0f` and the default shrink threshold of `0.25f`.
* growth factor and the default shrink threshold.
*
* The allocated buffer will be at least one character larger than the given `capacity`, to reserve
* space for the terminating '\0'.
@ -318,15 +317,15 @@ ZYCORE_EXPORT ZYAN_REQUIRES_LIBC ZyanStatus ZyanStringDuplicate(ZyanString* dest
* This value is automatically adjusted to the size of the source
* string, if a smaller value was passed.
* @param allocator A pointer to a `ZyanAllocator` instance.
* @param growth_factor The growth factor (from `1.0f` to `x.xf`).
* @param shrink_threshold The shrink threshold (from `0.0f` to `1.0f`).
* @param growth_factor The growth factor.
* @param shrink_threshold The shrink threshold.
*
* @return A zyan status code.
*
* The behavior of this function is undefined, if `source` is a view into the `destination`
* string or `destination` points to an already initialized `ZyanString` instance.
*
* A growth factor of `1.0f` disables overallocation and a shrink threshold of `0.0f` disables
* A growth factor of `1` disables overallocation and a shrink threshold of `0` disables
* dynamic shrinking.
*
* The allocated buffer will be at least one character larger than the given `capacity`, to reserve
@ -336,7 +335,7 @@ ZYCORE_EXPORT ZYAN_REQUIRES_LIBC ZyanStatus ZyanStringDuplicate(ZyanString* dest
*/
ZYCORE_EXPORT ZyanStatus ZyanStringDuplicateEx(ZyanString* destination,
const ZyanStringView* source, ZyanUSize capacity, ZyanAllocator* allocator,
float growth_factor, float shrink_threshold);
ZyanU8 growth_factor, ZyanU8 shrink_threshold);
/**
* Initializes a new `ZyanString` instance by duplicating an existing string and
@ -387,7 +386,7 @@ ZYCORE_EXPORT ZyanStatus ZyanStringDuplicateCustomBuffer(ZyanString* destination
* string or `destination` points to an already initialized `ZyanString` instance.
*
* The memory for the string is dynamically allocated by the default allocator using the default
* growth factor of `2.0f` and the default shrink threshold of `0.25f`.
* growth factor and the default shrink threshold.
*
* The allocated buffer will be at least one character larger than the given `capacity`, to reserve
* space for the terminating '\0'.
@ -414,15 +413,15 @@ ZYCORE_EXPORT ZYAN_REQUIRES_LIBC ZyanStatus ZyanStringConcat(ZyanString* destina
* This value is automatically adjusted to the combined size of the
* source strings, if a smaller value was passed.
* @param allocator A pointer to a `ZyanAllocator` instance.
* @param growth_factor The growth factor (from `1.0f` to `x.xf`).
* @param shrink_threshold The shrink threshold (from `0.0f` to `1.0f`).
* @param growth_factor The growth factor.
* @param shrink_threshold The shrink threshold.
*
* @return A zyan status code.
*
* The behavior of this function is undefined, if `s1` or `s2` are views into the `destination`
* string or `destination` points to an already initialized `ZyanString` instance.
*
* A growth factor of `1.0f` disables overallocation and a shrink threshold of `0.0f` disables
* A growth factor of `1` disables overallocation and a shrink threshold of `0` disables
* dynamic shrinking.
*
* The allocated buffer will be at least one character larger than the given `capacity`, to reserve
@ -431,8 +430,8 @@ ZYCORE_EXPORT ZYAN_REQUIRES_LIBC ZyanStatus ZyanStringConcat(ZyanString* destina
* Finalization with `ZyanStringDestroy` is required for all strings created by this function.
*/
ZYCORE_EXPORT ZyanStatus ZyanStringConcatEx(ZyanString* destination, const ZyanStringView* s1,
const ZyanStringView* s2, ZyanUSize capacity, ZyanAllocator* allocator, float growth_factor,
float shrink_threshold);
const ZyanStringView* s2, ZyanUSize capacity, ZyanAllocator* allocator, ZyanU8 growth_factor,
ZyanU8 shrink_threshold);
/**
* Initializes a new `ZyanString` instance by concatenating two existing strings and
@ -531,8 +530,8 @@ ZYCORE_EXPORT ZyanStatus ZyanStringViewGetSize(const ZyanStringView* view, ZyanU
*
* @warning The string is not guaranteed to be null terminated!
*
* @param string A pointer to the `ZyanStringView` instance.
* @param value Receives a pointer to the C-style string.
* @param view A pointer to the `ZyanStringView` instance.
* @param buffer Receives a pointer to the C-style string.
*
* @return A zyan status code.
*/
@ -741,7 +740,7 @@ ZYCORE_EXPORT ZyanStatus ZyanStringLPosI(const ZyanStringView* haystack,
* `index`.
*
* @return `ZYAN_STATUS_TRUE`, if the needle was found, `ZYAN_STATUS_FALSE`, if not, or another
* zyan status code, if an error occured.
* zyan status code, if an error occurred.
*
* The `found_index` is set to `-1`, if the needle was not found.
*/
@ -758,7 +757,7 @@ ZYCORE_EXPORT ZyanStatus ZyanStringLPosIEx(const ZyanStringView* haystack,
* `needle`.
*
* @return `ZYAN_STATUS_TRUE`, if the needle was found, `ZYAN_STATUS_FALSE`, if not, or another
* zyan status code, if an error occured.
* zyan status code, if an error occurred.
*
* The `found_index` is set to `-1`, if the needle was not found.
*/
@ -778,7 +777,7 @@ ZYCORE_EXPORT ZyanStatus ZyanStringRPos(const ZyanStringView* haystack,
* `index`.
*
* @return `ZYAN_STATUS_TRUE`, if the needle was found, `ZYAN_STATUS_FALSE`, if not, or another
* zyan status code, if an error occured.
* zyan status code, if an error occurred.
*
* The `found_index` is set to `-1`, if the needle was not found.
*/
@ -795,7 +794,7 @@ ZYCORE_EXPORT ZyanStatus ZyanStringRPosEx(const ZyanStringView* haystack,
* `needle`.
*
* @return `ZYAN_STATUS_TRUE`, if the needle was found, `ZYAN_STATUS_FALSE`, if not, or another
* zyan status code, if an error occured.
* zyan status code, if an error occurred.
*
* The `found_index` is set to `-1`, if the needle was not found.
*/
@ -815,7 +814,7 @@ ZYCORE_EXPORT ZyanStatus ZyanStringRPosI(const ZyanStringView* haystack,
* `index`.
*
* @return `ZYAN_STATUS_TRUE`, if the needle was found, `ZYAN_STATUS_FALSE`, if not, or another
* zyan status code, if an error occured.
* zyan status code, if an error occurred.
*
* The `found_index` is set to `-1`, if the needle was not found.
*/
@ -841,7 +840,7 @@ ZYCORE_EXPORT ZyanStatus ZyanStringRPosIEx(const ZyanStringView* haystack,
* in `s1` than in `s2`.
*
* @return `ZYAN_STATUS_TRUE`, if the strings are equal, `ZYAN_STATUS_FALSE`, if not, or another
* zyan status code, if an error occured.
* zyan status code, if an error occurred.
*/
ZYCORE_EXPORT ZyanStatus ZyanStringCompare(const ZyanStringView* s1, const ZyanStringView* s2,
ZyanI32* result);
@ -861,7 +860,7 @@ ZYCORE_EXPORT ZyanStatus ZyanStringCompare(const ZyanStringView* s1, const ZyanS
* in `s1` than in `s2`.
*
* @return `ZYAN_STATUS_TRUE`, if the strings are equal, `ZYAN_STATUS_FALSE`, if not, or another
* zyan status code, if an error occured.
* zyan status code, if an error occurred.
*/
ZYCORE_EXPORT ZyanStatus ZyanStringCompareI(const ZyanStringView* s1, const ZyanStringView* s2,
ZyanI32* result);

View file

@ -77,6 +77,34 @@
# else
# error "Unsupported compiler for no-libc mode."
# endif
# if defined(ZYAN_MSVC)
# define ZYAN_INT8_MIN (-127i8 - 1)
# define ZYAN_INT16_MIN (-32767i16 - 1)
# define ZYAN_INT32_MIN (-2147483647i32 - 1)
# define ZYAN_INT64_MIN (-9223372036854775807i64 - 1)
# define ZYAN_INT8_MAX 127i8
# define ZYAN_INT16_MAX 32767i16
# define ZYAN_INT32_MAX 2147483647i32
# define ZYAN_INT64_MAX 9223372036854775807i64
# define ZYAN_UINT8_MAX 0xffui8
# define ZYAN_UINT16_MAX 0xffffui16
# define ZYAN_UINT32_MAX 0xffffffffui32
# define ZYAN_UINT64_MAX 0xffffffffffffffffui64
# else
# define ZYAN_INT8_MAX __INT8_MAX__
# define ZYAN_INT8_MIN (-ZYAN_INT8_MAX - 1)
# define ZYAN_INT16_MAX __INT16_MAX__
# define ZYAN_INT16_MIN (-ZYAN_INT16_MAX - 1)
# define ZYAN_INT32_MAX __INT32_MAX__
# define ZYAN_INT32_MIN (-ZYAN_INT32_MAX - 1)
# define ZYAN_INT64_MAX __INT64_MAX__
# define ZYAN_INT64_MIN (-ZYAN_INT64_MAX - 1)
# define ZYAN_UINT8_MAX __UINT8_MAX__
# define ZYAN_UINT16_MAX __UINT16_MAX__
# define ZYAN_UINT32_MAX __UINT32_MAX__
# define ZYAN_UINT64_MAX __UINT64_MAX__
# endif
#else
// If is LibC present, we use stdint types.
# include <stdint.h>
@ -93,6 +121,19 @@
typedef ptrdiff_t ZyanISize;
typedef uintptr_t ZyanUPointer;
typedef intptr_t ZyanIPointer;
# define ZYAN_INT8_MIN INT8_MIN
# define ZYAN_INT16_MIN INT16_MIN
# define ZYAN_INT32_MIN INT32_MIN
# define ZYAN_INT64_MIN INT64_MIN
# define ZYAN_INT8_MAX INT8_MAX
# define ZYAN_INT16_MAX INT16_MAX
# define ZYAN_INT32_MAX INT32_MAX
# define ZYAN_INT64_MAX INT64_MAX
# define ZYAN_UINT8_MAX UINT8_MAX
# define ZYAN_UINT16_MAX UINT16_MAX
# define ZYAN_UINT32_MAX UINT32_MAX
# define ZYAN_UINT64_MAX UINT64_MAX
#endif
// Verify size assumptions.
@ -122,7 +163,7 @@ ZYAN_STATIC_ASSERT((ZyanI64)-1 >> 1 < (ZyanI64)((ZyanU64)-1 >> 1));
/**
* Defines the `ZyanVoidPointer` data-type.
*/
typedef char* ZyanVoidPointer;
typedef void* ZyanVoidPointer;
/**
* Defines the `ZyanConstVoidPointer` data-type.
@ -139,8 +180,8 @@ typedef const void* ZyanConstVoidPointer;
/* Boolean */
/* ---------------------------------------------------------------------------------------------- */
#define ZYAN_FALSE 0
#define ZYAN_TRUE 1
#define ZYAN_FALSE 0u
#define ZYAN_TRUE 1u
/**
* Defines the `ZyanBool` data-type.

View file

@ -32,7 +32,6 @@
#ifndef ZYCORE_VECTOR_H
#define ZYCORE_VECTOR_H
#include <ZycoreExportConfig.h>
#include <Zycore/Allocator.h>
#include <Zycore/Comparison.h>
#include <Zycore/Object.h>
@ -56,12 +55,12 @@ extern "C" {
/**
* The default growth factor for all vector instances.
*/
#define ZYAN_VECTOR_DEFAULT_GROWTH_FACTOR 2.00f
#define ZYAN_VECTOR_DEFAULT_GROWTH_FACTOR 2
/**
* The default shrink threshold for all vector instances.
*/
#define ZYAN_VECTOR_DEFAULT_SHRINK_THRESHOLD 0.25f
#define ZYAN_VECTOR_DEFAULT_SHRINK_THRESHOLD 4
/* ============================================================================================== */
/* Enums and types */
@ -82,11 +81,11 @@ typedef struct ZyanVector_
/**
* The growth factor.
*/
float growth_factor;
ZyanU8 growth_factor;
/**
* The shrink threshold.
*/
float shrink_threshold;
ZyanU8 shrink_threshold;
/**
* The current number of elements in the vector.
*/
@ -123,8 +122,8 @@ typedef struct ZyanVector_
#define ZYAN_VECTOR_INITIALIZER \
{ \
/* allocator */ ZYAN_NULL, \
/* growth_factor */ 0.0f, \
/* shrink_threshold */ 0.0f, \
/* growth_factor */ 0, \
/* shrink_threshold */ 0, \
/* size */ 0, \
/* capacity */ 0, \
/* element_size */ 0, \
@ -223,7 +222,7 @@ typedef struct ZyanVector_
* @return A zyan status code.
*
* The memory for the vector elements is dynamically allocated by the default allocator using the
* default growth factor of `2.0f` and the default shrink threshold of `0.25f`.
* default growth factor and the default shrink threshold.
*
* Finalization with `ZyanVectorDestroy` is required for all instances created by this function.
*/
@ -242,19 +241,19 @@ ZYCORE_EXPORT ZYAN_REQUIRES_LIBC ZyanStatus ZyanVectorInit(ZyanVector* vector,
* @param destructor A destructor callback that is invoked every time an item is deleted,
* or `ZYAN_NULL` if not needed.
* @param allocator A pointer to a `ZyanAllocator` instance.
* @param growth_factor The growth factor (from `1.0f` to `x.xf`).
* @param shrink_threshold The shrink threshold (from `0.0f` to `1.0f`).
* @param growth_factor The growth factor.
* @param shrink_threshold The shrink threshold.
*
* @return A zyan status code.
*
* A growth factor of `1.0f` disables overallocation and a shrink threshold of `0.0f` disables
* A growth factor of `1` disables overallocation and a shrink threshold of `0` disables
* dynamic shrinking.
*
* Finalization with `ZyanVectorDestroy` is required for all instances created by this function.
*/
ZYCORE_EXPORT ZyanStatus ZyanVectorInitEx(ZyanVector* vector, ZyanUSize element_size,
ZyanUSize capacity, ZyanMemberProcedure destructor, ZyanAllocator* allocator,
float growth_factor, float shrink_threshold);
ZyanU8 growth_factor, ZyanU8 shrink_threshold);
/**
* Initializes the given `ZyanVector` instance and configures it to use a custom user
@ -302,7 +301,7 @@ ZYCORE_EXPORT ZyanStatus ZyanVectorDestroy(ZyanVector* vector);
* @return A zyan status code.
*
* The memory for the vector is dynamically allocated by the default allocator using the default
* growth factor of `2.0f` and the default shrink threshold of `0.25f`.
* growth factor and the default shrink threshold.
*
* Finalization with `ZyanVectorDestroy` is required for all instances created by this function.
*/
@ -322,18 +321,18 @@ ZYCORE_EXPORT ZYAN_REQUIRES_LIBC ZyanStatus ZyanVectorDuplicate(ZyanVector* dest
* This value is automatically adjusted to the size of the source
* vector, if a smaller value was passed.
* @param allocator A pointer to a `ZyanAllocator` instance.
* @param growth_factor The growth factor (from `1.0f` to `x.xf`).
* @param shrink_threshold The shrink threshold (from `0.0f` to `1.0f`).
* @param growth_factor The growth factor.
* @param shrink_threshold The shrink threshold.
*
* @return A zyan status code.
*
* A growth factor of `1.0f` disables overallocation and a shrink threshold of `0.0f` disables
* A growth factor of `1` disables overallocation and a shrink threshold of `0` disables
* dynamic shrinking.
*
* Finalization with `ZyanVectorDestroy` is required for all instances created by this function.
*/
ZYCORE_EXPORT ZyanStatus ZyanVectorDuplicateEx(ZyanVector* destination, const ZyanVector* source,
ZyanUSize capacity, ZyanAllocator* allocator, float growth_factor, float shrink_threshold);
ZyanUSize capacity, ZyanAllocator* allocator, ZyanU8 growth_factor, ZyanU8 shrink_threshold);
/**
* Initializes a new `ZyanVector` instance by duplicating an existing vector and
@ -365,7 +364,7 @@ ZYCORE_EXPORT ZyanStatus ZyanVectorDuplicateCustomBuffer(ZyanVector* destination
* @param index The element index.
*
* @return A constant pointer to the desired element in the vector or `ZYAN_NULL`, if an error
* occured.
* occurred.
*
* Note that the returned pointer might get invalid when the vector is resized by either a manual
* call to the memory-management functions or implicitly by inserting or removing elements.
@ -382,7 +381,7 @@ ZYCORE_EXPORT const void* ZyanVectorGet(const ZyanVector* vector, ZyanUSize inde
* @param index The element index.
*
* @return A mutable pointer to the desired element in the vector or `ZYAN_NULL`, if an error
* occured.
* occurred.
*
* Note that the returned pointer might get invalid when the vector is resized by either a manual
* call to the memory-management functions or implicitly by inserting or removing elements.
@ -576,7 +575,7 @@ ZYCORE_EXPORT ZyanStatus ZyanVectorClear(ZyanVector* vector);
* @param comparison The comparison function to use.
*
* @return `ZYAN_STATUS_TRUE` if the element was found, `ZYAN_STATUS_FALSE` if not or a generic
* zyan status code if an error occured.
* zyan status code if an error occurred.
*
* The `found_index` is set to `-1`, if the element was not found.
*/
@ -594,7 +593,7 @@ ZYCORE_EXPORT ZyanStatus ZyanVectorFind(const ZyanVector* vector, const void* el
* @param count The maximum number of elements to iterate, beginning from the start `index`.
*
* @return `ZYAN_STATUS_TRUE` if the element was found, `ZYAN_STATUS_FALSE` if not or a generic
* zyan status code if an error occured.
* zyan status code if an error occurred.
*
* The `found_index` is set to `-1`, if the element was not found.
*/
@ -611,7 +610,7 @@ ZYCORE_EXPORT ZyanStatus ZyanVectorFindEx(const ZyanVector* vector, const void*
* @param comparison The comparison function to use.
*
* @return `ZYAN_STATUS_TRUE` if the element was found, `ZYAN_STATUS_FALSE` if not or a generic
* zyan status code if an error occured.
* zyan status code if an error occurred.
*
* If found, `found_index` contains the zero-based index of `element`. If not found, `found_index`
* contains the index of the first entry larger than `element`.
@ -633,7 +632,7 @@ ZYCORE_EXPORT ZyanStatus ZyanVectorBinarySearch(const ZyanVector* vector, const
* @param count The maximum number of elements to iterate, beginning from the start `index`.
*
* @return `ZYAN_STATUS_TRUE` if the element was found, `ZYAN_STATUS_FALSE` if not or a generic
* zyan status code if an error occured.
* zyan status code if an error occurred.
*
* If found, `found_index` contains the zero-based index of `element`. If not found, `found_index`
* contains the index of the first entry larger than `element`.

View file

@ -32,7 +32,6 @@
#ifndef ZYCORE_H
#define ZYCORE_H
#include <ZycoreExportConfig.h>
#include <Zycore/Types.h>
// TODO:
@ -52,7 +51,7 @@ extern "C" {
/**
* A macro that defines the zycore version.
*/
#define ZYCORE_VERSION (ZyanU64)0x0001000000000000
#define ZYCORE_VERSION (ZyanU64)0x0001000400010000
/* ---------------------------------------------------------------------------------------------- */
/* Helper macros */

Binary file not shown.

View file

@ -26,6 +26,8 @@
#include <Zycore/API/Memory.h>
#ifndef ZYAN_NO_LIBC
#if defined(ZYAN_WINDOWS)
#elif defined(ZYAN_POSIX)
@ -126,3 +128,5 @@ ZyanStatus ZyanMemoryVirtualFree(void* address, ZyanUSize size)
/* ---------------------------------------------------------------------------------------------- */
/* ============================================================================================== */
#endif /* ZYAN_NO_LIBC */

View file

@ -25,14 +25,21 @@
***************************************************************************************************/
#include <Zycore/Defines.h>
#if defined(ZYAN_WINDOWS)
# include <windows.h>
#include <Zycore/API/Process.h>
#ifndef ZYAN_NO_LIBC
#if defined(ZYAN_WINDOWS)
#if defined(ZYAN_KERNEL)
# include <wdm.h>
#else
# include <windows.h>
#endif
#elif defined(ZYAN_POSIX)
# include <sys/mman.h>
#else
# error "Unsupported platform detected"
#endif
#include <Zycore/API/Process.h>
/* ============================================================================================== */
/* Exported functions */
@ -66,3 +73,5 @@ ZyanStatus ZyanProcessFlushInstructionCache(void* address, ZyanUSize size)
/* ---------------------------------------------------------------------------------------------- */
/* ============================================================================================== */
#endif /* ZYAN_NO_LIBC */

View file

@ -26,6 +26,8 @@
#include <Zycore/API/Synchronization.h>
#ifndef ZYAN_NO_LIBC
/* ============================================================================================== */
/* Internal functions */
/* ============================================================================================== */
@ -198,3 +200,5 @@ ZyanStatus ZyanCriticalSectionDelete(ZyanCriticalSection* critical_section)
#endif
/* ============================================================================================== */
#endif /* ZYAN_NO_LIBC */

View file

@ -26,6 +26,8 @@
#include <Zycore/API/Terminal.h>
#ifndef ZYAN_NO_LIBC
#if defined(ZYAN_POSIX)
# include <unistd.h>
#elif defined(ZYAN_WINDOWS)
@ -154,3 +156,5 @@ ZyanStatus ZyanTerminalIsTTY(ZyanStandardStream stream)
}
/* ============================================================================================== */
#endif /* ZYAN_NO_LIBC */

View file

@ -26,14 +26,62 @@
#include <Zycore/API/Thread.h>
#ifndef ZYAN_NO_LIBC
/* ============================================================================================== */
/* Internal functions */
/* ============================================================================================== */
/* ---------------------------------------------------------------------------------------------- */
/* */
/* Legacy Windows import declarations */
/* ---------------------------------------------------------------------------------------------- */
#if defined(ZYAN_WINDOWS) && defined(_WIN32_WINNT) && \
(_WIN32_WINNT >= 0x0501) && (_WIN32_WINNT < 0x0600)
/**
* The Windows SDK conditionally declares the following prototypes: the target OS must be Vista
* (0x0600) or above. MSDN states the same incorrect minimum requirement for the Fls* functions.
*
* However, these functions exist and work perfectly fine on XP (SP3) and Server 2003.
* Preserve backward compatibility with these OSes by declaring the prototypes here if needed.
*/
#ifndef FLS_OUT_OF_INDEXES
#define FLS_OUT_OF_INDEXES ((DWORD)0xFFFFFFFF)
#endif
WINBASEAPI
DWORD
WINAPI
FlsAlloc(
_In_opt_ PFLS_CALLBACK_FUNCTION lpCallback
);
WINBASEAPI
PVOID
WINAPI
FlsGetValue(
_In_ DWORD dwFlsIndex
);
WINBASEAPI
BOOL
WINAPI
FlsSetValue(
_In_ DWORD dwFlsIndex,
_In_opt_ PVOID lpFlsData
);
WINBASEAPI
BOOL
WINAPI
FlsFree(
_In_ DWORD dwFlsIndex
);
#endif /* (_WIN32_WINNT >= 0x0501) && (_WIN32_WINNT < 0x0600)*/
/* ---------------------------------------------------------------------------------------------- */
@ -192,3 +240,5 @@ ZyanStatus ZyanThreadTlsSetValue(ZyanThreadTlsIndex index, void* data)
#endif
/* ============================================================================================== */
#endif /* ZYAN_NO_LIBC */

View file

@ -31,8 +31,8 @@
/* Internal constants */
/* ============================================================================================== */
#define ZYAN_BITSET_GROWTH_FACTOR 2.00f
#define ZYAN_BITSET_SHRINK_THRESHOLD 0.50f
#define ZYAN_BITSET_GROWTH_FACTOR 2
#define ZYAN_BITSET_SHRINK_THRESHOLD 2
/* ============================================================================================== */
/* Internal macros */
@ -56,7 +56,7 @@
* @return The amount of bytes needed to fit `x` bits.
*/
#define ZYAN_BITSET_BITS_TO_BYTES(x) \
ZYAN_BITSET_CEIL((x) / 8.0f)
ZYAN_BITSET_CEIL((x) / 8)
/**
* Returns the offset of the given bit.
@ -140,7 +140,7 @@ ZyanStatus ZyanBitsetInit(ZyanBitset* bitset, ZyanUSize count)
#endif // ZYAN_NO_LIBC
ZyanStatus ZyanBitsetInitEx(ZyanBitset* bitset, ZyanUSize count, ZyanAllocator* allocator,
float growth_factor, float shrink_threshold)
ZyanU8 growth_factor, ZyanU8 shrink_threshold)
{
if (!bitset)
{

View file

@ -83,7 +83,7 @@ static const ZyanStringView STR_SUB = ZYAN_DEFINE_STRING_VIEW("-");
/* Decimal */
/* ---------------------------------------------------------------------------------------------- */
#if defined(ZYAN_X86) || defined(ZYAN_ARM) || defined(ZYAN_EMSCRIPTEN)
#if defined(ZYAN_X86) || defined(ZYAN_ARM) || defined(ZYAN_EMSCRIPTEN) || defined(ZYAN_WASM) || defined(ZYAN_PPC)
ZyanStatus ZyanStringAppendDecU32(ZyanString* string, ZyanU32 value, ZyanU8 padding_length)
{
if (!string)
@ -179,7 +179,7 @@ ZyanStatus ZyanStringAppendDecU64(ZyanString* string, ZyanU64 value, ZyanU8 padd
/* Hexadecimal */
/* ---------------------------------------------------------------------------------------------- */
#if defined(ZYAN_X86) || defined(ZYAN_ARM) || defined(ZYAN_EMSCRIPTEN)
#if defined(ZYAN_X86) || defined(ZYAN_ARM) || defined(ZYAN_EMSCRIPTEN) || defined(ZYAN_WASM) || defined(ZYAN_PPC)
ZyanStatus ZyanStringAppendHexU32(ZyanString* string, ZyanU32 value, ZyanU8 padding_length,
ZyanBool uppercase)
{
@ -423,7 +423,7 @@ ZyanStatus ZyanStringAppendFormat(ZyanString* string, const char* format, ...)
ZyanStatus ZyanStringAppendDecU(ZyanString* string, ZyanU64 value, ZyanU8 padding_length)
{
#if defined(ZYAN_X64) || defined(ZYAN_AARCH64)
#if defined(ZYAN_X64) || defined(ZYAN_AARCH64) || defined(ZYAN_PPC64) || defined(ZYAN_RISCV64)
return ZyanStringAppendDecU64(string, value, padding_length);
#else
// Working with 64-bit values is slow on non 64-bit systems
@ -464,7 +464,7 @@ ZyanStatus ZyanStringAppendDecS(ZyanString* string, ZyanI64 value, ZyanU8 paddin
ZyanStatus ZyanStringAppendHexU(ZyanString* string, ZyanU64 value, ZyanU8 padding_length,
ZyanBool uppercase)
{
#if defined(ZYAN_X64) || defined(ZYAN_AARCH64)
#if defined(ZYAN_X64) || defined(ZYAN_AARCH64) || defined(ZYAN_PPC64) || defined(ZYAN_RISCV64)
return ZyanStringAppendHexU64(string, value, padding_length, uppercase);
#else
// Working with 64-bit values is slow on non 64-bit systems

View file

@ -62,7 +62,7 @@ ZyanStatus ZyanStringInit(ZyanString* string, ZyanUSize capacity)
#endif // ZYAN_NO_LIBC
ZyanStatus ZyanStringInitEx(ZyanString* string, ZyanUSize capacity, ZyanAllocator* allocator,
float growth_factor, float shrink_threshold)
ZyanU8 growth_factor, ZyanU8 shrink_threshold)
{
if (!string)
{
@ -133,7 +133,7 @@ ZyanStatus ZyanStringDuplicate(ZyanString* destination, const ZyanStringView* so
#endif // ZYAN_NO_LIBC
ZyanStatus ZyanStringDuplicateEx(ZyanString* destination, const ZyanStringView* source,
ZyanUSize capacity, ZyanAllocator* allocator, float growth_factor, float shrink_threshold)
ZyanUSize capacity, ZyanAllocator* allocator, ZyanU8 growth_factor, ZyanU8 shrink_threshold)
{
if (!source || !source->string.vector.size)
{
@ -194,8 +194,8 @@ ZyanStatus ZyanStringConcat(ZyanString* destination, const ZyanStringView* s1,
#endif // ZYAN_NO_LIBC
ZyanStatus ZyanStringConcatEx(ZyanString* destination, const ZyanStringView* s1,
const ZyanStringView* s2, ZyanUSize capacity, ZyanAllocator* allocator, float growth_factor,
float shrink_threshold)
const ZyanStringView* s2, ZyanUSize capacity, ZyanAllocator* allocator, ZyanU8 growth_factor,
ZyanU8 shrink_threshold)
{
if (!s1 || !s2 || !s1->string.vector.size || !s2->string.vector.size)
{

View file

@ -52,7 +52,7 @@
* @return `ZYAN_TRUE`, if the vector should shrink or `ZYAN_FALSE`, if not.
*/
#define ZYCORE_VECTOR_SHOULD_SHRINK(size, capacity, threshold) \
((size) < (capacity) * (threshold))
(((threshold) != 0) && ((size) * (threshold) < (capacity)))
/**
* Returns the offset of the element at the given `index`.
@ -119,8 +119,7 @@ static ZyanStatus ZyanVectorReallocate(ZyanVector* vector, ZyanUSize capacity)
}
/**
* Shifts all elements starting at the specified `index` by the amount of
* `count` to the left.
* Shifts all elements starting at the specified `index` by the amount of `count` to the left.
*
* @param vector A pointer to the `ZyanVector` instance.
* @param index The start index.
@ -136,17 +135,16 @@ static ZyanStatus ZyanVectorShiftLeft(ZyanVector* vector, ZyanUSize index, ZyanU
ZYAN_ASSERT(count > 0);
//ZYAN_ASSERT((ZyanISize)count - (ZyanISize)index + 1 >= 0);
void* const source = ZYCORE_VECTOR_OFFSET(vector, index + count);
void* const dest = ZYCORE_VECTOR_OFFSET(vector, index);
const ZyanUSize size = (vector->size - index - count) * vector->element_size;
const void* const source = ZYCORE_VECTOR_OFFSET(vector, index + count);
void* const dest = ZYCORE_VECTOR_OFFSET(vector, index);
const ZyanUSize size = (vector->size - index - count) * vector->element_size;
ZYAN_MEMMOVE(dest, source, size);
return ZYAN_STATUS_SUCCESS;
}
/**
* Shifts all elements starting at the specified `index` by the amount of
* `count` to the right.
* Shifts all elements starting at the specified `index` by the amount of `count` to the right.
*
* @param vector A pointer to the `ZyanVector` instance.
* @param index The start index.
@ -162,9 +160,9 @@ static ZyanStatus ZyanVectorShiftRight(ZyanVector* vector, ZyanUSize index, Zyan
ZYAN_ASSERT(count > 0);
ZYAN_ASSERT(vector->size + count <= vector->capacity);
void* const source = ZYCORE_VECTOR_OFFSET(vector, index);
void* const dest = ZYCORE_VECTOR_OFFSET(vector, index + count);
const ZyanUSize size = (vector->size - index) * vector->element_size;
const void* const source = ZYCORE_VECTOR_OFFSET(vector, index);
void* const dest = ZYCORE_VECTOR_OFFSET(vector, index + count);
const ZyanUSize size = (vector->size - index) * vector->element_size;
ZYAN_MEMMOVE(dest, source, size);
return ZYAN_STATUS_SUCCESS;
@ -192,11 +190,10 @@ ZyanStatus ZyanVectorInit(ZyanVector* vector, ZyanUSize element_size, ZyanUSize
#endif // ZYAN_NO_LIBC
ZyanStatus ZyanVectorInitEx(ZyanVector* vector, ZyanUSize element_size, ZyanUSize capacity,
ZyanMemberProcedure destructor, ZyanAllocator* allocator, float growth_factor,
float shrink_threshold)
ZyanMemberProcedure destructor, ZyanAllocator* allocator, ZyanU8 growth_factor,
ZyanU8 shrink_threshold)
{
if (!vector || !element_size || !allocator || (growth_factor < 1.0f) ||
(shrink_threshold < 0.0f) || (shrink_threshold > 1.0f))
if (!vector || !element_size || !allocator || (growth_factor < 1))
{
return ZYAN_STATUS_INVALID_ARGUMENT;
}
@ -225,8 +222,8 @@ ZyanStatus ZyanVectorInitCustomBuffer(ZyanVector* vector, ZyanUSize element_size
}
vector->allocator = ZYAN_NULL;
vector->growth_factor = 1.0f;
vector->shrink_threshold = 0.0f;
vector->growth_factor = 1;
vector->shrink_threshold = 0;
vector->size = 0;
vector->capacity = capacity;
vector->element_size = element_size;
@ -281,7 +278,7 @@ ZyanStatus ZyanVectorDuplicate(ZyanVector* destination, const ZyanVector* source
#endif // ZYAN_NO_LIBC
ZyanStatus ZyanVectorDuplicateEx(ZyanVector* destination, const ZyanVector* source,
ZyanUSize capacity, ZyanAllocator* allocator, float growth_factor, float shrink_threshold)
ZyanUSize capacity, ZyanAllocator* allocator, ZyanU8 growth_factor, ZyanU8 shrink_threshold)
{
if (!source)
{
@ -774,8 +771,9 @@ ZyanStatus ZyanVectorResizeEx(ZyanVector* vector, ZyanUSize size, const void* in
if (ZYCORE_VECTOR_SHOULD_GROW(size, vector->capacity) ||
ZYCORE_VECTOR_SHOULD_SHRINK(size, vector->capacity, vector->shrink_threshold))
{
ZYAN_ASSERT(vector->growth_factor >= 1);
ZYAN_CHECK(ZyanVectorReallocate(vector, (ZyanUSize)(size * vector->growth_factor)));
};
}
if (initializer && (size > vector->size))
{

View file

@ -146,8 +146,8 @@ TEST(VectorTest, InitBasic)
ASSERT_EQ(ZyanVectorInit(&vector, sizeof(ZyanU64), 0,
reinterpret_cast<ZyanMemberProcedure>(ZYAN_NULL)), ZYAN_STATUS_SUCCESS);
EXPECT_EQ(vector.allocator, ZyanAllocatorDefault());
EXPECT_FLOAT_EQ(vector.growth_factor, ZYAN_VECTOR_DEFAULT_GROWTH_FACTOR);
EXPECT_FLOAT_EQ(vector.shrink_threshold, ZYAN_VECTOR_DEFAULT_SHRINK_THRESHOLD);
EXPECT_EQ(vector.growth_factor, ZYAN_VECTOR_DEFAULT_GROWTH_FACTOR);
EXPECT_EQ(vector.shrink_threshold, ZYAN_VECTOR_DEFAULT_SHRINK_THRESHOLD);
EXPECT_EQ(vector.size, static_cast<ZyanUSize>(0));
EXPECT_EQ(vector.capacity, static_cast<ZyanUSize>(ZYAN_VECTOR_MIN_CAPACITY));
EXPECT_EQ(vector.element_size, sizeof(ZyanU64));
@ -166,11 +166,11 @@ TEST(VectorTest, InitAdvanced)
ZyanVector vector;
ASSERT_EQ(ZyanVectorInitEx(&vector, sizeof(ZyanU16), 0,
reinterpret_cast<ZyanMemberProcedure>(ZYAN_NULL), ZyanAllocatorDefault(), 1.0f, 0.0f),
reinterpret_cast<ZyanMemberProcedure>(ZYAN_NULL), ZyanAllocatorDefault(), 1, 0),
ZYAN_STATUS_SUCCESS);
EXPECT_EQ(vector.allocator, ZyanAllocatorDefault());
EXPECT_FLOAT_EQ(vector.growth_factor, 1.0f);
EXPECT_FLOAT_EQ(vector.shrink_threshold, 0.0f);
EXPECT_EQ(vector.growth_factor, 1);
EXPECT_EQ(vector.shrink_threshold, 0);
EXPECT_EQ(vector.size, static_cast<ZyanUSize>(0));
EXPECT_EQ(vector.capacity, static_cast<ZyanUSize>(ZYAN_VECTOR_MIN_CAPACITY));
EXPECT_EQ(vector.element_size, sizeof(ZyanU16));
@ -179,7 +179,7 @@ TEST(VectorTest, InitAdvanced)
// Custom capacity
EXPECT_EQ(ZyanVectorInitEx(&vector, sizeof(ZyanU16), 10,
reinterpret_cast<ZyanMemberProcedure>(ZYAN_NULL), ZyanAllocatorDefault(), 1.0f, 0.0f),
reinterpret_cast<ZyanMemberProcedure>(ZYAN_NULL), ZyanAllocatorDefault(), 1, 0),
ZYAN_STATUS_SUCCESS);
EXPECT_EQ(vector.capacity, static_cast<ZyanUSize>(ZYAN_MAX(ZYAN_VECTOR_MIN_CAPACITY, 10)));
EXPECT_EQ(ZyanVectorDestroy(&vector), ZYAN_STATUS_SUCCESS);
@ -196,8 +196,8 @@ TEST(VectorTest, InitCustomBuffer)
ZYAN_ARRAY_LENGTH(buffer), reinterpret_cast<ZyanMemberProcedure>(ZYAN_NULL)),
ZYAN_STATUS_SUCCESS);
EXPECT_EQ(vector.allocator, ZYAN_NULL);
EXPECT_FLOAT_EQ(vector.growth_factor, 1.0f);
EXPECT_FLOAT_EQ(vector.shrink_threshold, 0.0f);
EXPECT_EQ(vector.growth_factor, 1);
EXPECT_EQ(vector.shrink_threshold, 0);
EXPECT_EQ(vector.size, static_cast<ZyanUSize>(0));
EXPECT_EQ(vector.capacity, ZYAN_ARRAY_LENGTH(buffer));
EXPECT_EQ(vector.element_size, sizeof(ZyanU16));
@ -249,6 +249,40 @@ TEST(VectorTest, Destructor)
}
}
TEST(VectorTest, TestGrowingAndShrinking)
{
ZyanVector vector;
ASSERT_EQ(ZyanVectorInit(&vector, sizeof(ZyanU64), 0,
reinterpret_cast<ZyanMemberProcedure>(ZYAN_NULL)), ZYAN_STATUS_SUCCESS);
for (ZyanU64 i = 0; i < 100; ++i)
{
ZyanUSize expected_capacity = vector.capacity;
if (expected_capacity < (i + 1))
{
expected_capacity = (expected_capacity + 1) * vector.growth_factor;
}
ASSERT_EQ(ZyanVectorPushBack(&vector, &i), ZYAN_STATUS_SUCCESS);
ASSERT_EQ(vector.capacity, expected_capacity);
}
for (ZyanU64 i = 100; i > 0; --i)
{
const auto index = static_cast<ZyanUSize>(i - 1);
ZyanUSize expected_capacity = vector.capacity;
if ((vector.shrink_threshold != 0) && (index * vector.shrink_threshold < vector.capacity))
{
expected_capacity = ZYAN_MAX(1, (ZyanUSize)(index * vector.growth_factor));
}
ASSERT_EQ(ZyanVectorDelete(&vector, index), ZYAN_STATUS_SUCCESS);
ASSERT_EQ(vector.capacity, expected_capacity);
}
EXPECT_EQ(ZyanVectorDestroy(&vector), ZYAN_STATUS_SUCCESS);
}
TEST_P(VectorTestFilled, ElementAccess)
{
static const ZyanU64 element_in = 1337;