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:
parent
80d62f2249
commit
cd2ede593a
35 changed files with 1120 additions and 228 deletions
1
.github/FUNDING.yml
vendored
Normal file
1
.github/FUNDING.yml
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
github: flobernd
|
86
.github/workflows/main.yml
vendored
Normal file
86
.github/workflows/main.yml
vendored
Normal 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 }}
|
188
CMakeLists.txt
188
CMakeLists.txt
|
@ -2,13 +2,18 @@ if (TARGET Zycore)
|
||||||
return()
|
return()
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
|
cmake_minimum_required(VERSION 3.9 FATAL_ERROR)
|
||||||
include(GenerateExportHeader)
|
|
||||||
|
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(GNUInstallDirs)
|
||||||
include(CMakePackageConfigHelpers)
|
include(CMakePackageConfigHelpers)
|
||||||
|
|
||||||
project(Zycore VERSION 1.0.0.0 LANGUAGES C CXX)
|
|
||||||
|
|
||||||
# =============================================================================================== #
|
# =============================================================================================== #
|
||||||
# Overridable options #
|
# Overridable options #
|
||||||
# =============================================================================================== #
|
# =============================================================================================== #
|
||||||
|
@ -23,6 +28,9 @@ option(ZYAN_NO_LIBC
|
||||||
option(ZYAN_DEV_MODE
|
option(ZYAN_DEV_MODE
|
||||||
"Enable developer mode (-Wall, -Werror, ...)"
|
"Enable developer mode (-Wall, -Werror, ...)"
|
||||||
OFF)
|
OFF)
|
||||||
|
option(ZYAN_FORCE_ASSERTS
|
||||||
|
"Forces asserts in release builds."
|
||||||
|
OFF)
|
||||||
|
|
||||||
# Build configuration
|
# Build configuration
|
||||||
option(ZYCORE_BUILD_SHARED_LIB
|
option(ZYCORE_BUILD_SHARED_LIB
|
||||||
|
@ -35,12 +43,42 @@ option(ZYCORE_BUILD_TESTS
|
||||||
"Build tests"
|
"Build tests"
|
||||||
OFF)
|
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 #
|
# GoogleTest #
|
||||||
# =============================================================================================== #
|
# =============================================================================================== #
|
||||||
|
|
||||||
# Download and unpack googletest
|
# Search for GoogleTest, and fallback to downloading it if not found
|
||||||
if (ZYCORE_BUILD_TESTS)
|
if (ZYCORE_BUILD_TESTS)
|
||||||
|
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)
|
if (NOT DEFINED ZYCORE_DOWNLOADED_GTEST)
|
||||||
configure_file("CMakeLists.txt.in" "${CMAKE_BINARY_DIR}/gtest/download/CMakeLists.txt")
|
configure_file("CMakeLists.txt.in" "${CMAKE_BINARY_DIR}/gtest/download/CMakeLists.txt")
|
||||||
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
|
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
|
||||||
|
@ -64,52 +102,11 @@ if (ZYCORE_BUILD_TESTS)
|
||||||
|
|
||||||
add_subdirectory("${CMAKE_BINARY_DIR}/gtest/src" "${CMAKE_BINARY_DIR}/gtest/build"
|
add_subdirectory("${CMAKE_BINARY_DIR}/gtest/src" "${CMAKE_BINARY_DIR}/gtest/build"
|
||||||
EXCLUDE_FROM_ALL)
|
EXCLUDE_FROM_ALL)
|
||||||
|
endif ()
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
# =============================================================================================== #
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||||
# Exported functions #
|
include(zyan-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 ()
|
|
||||||
|
|
||||||
# =============================================================================================== #
|
# =============================================================================================== #
|
||||||
# Library configuration #
|
# Library configuration #
|
||||||
|
@ -119,16 +116,23 @@ if (ZYCORE_BUILD_SHARED_LIB)
|
||||||
add_library("Zycore" SHARED)
|
add_library("Zycore" SHARED)
|
||||||
else ()
|
else ()
|
||||||
add_library("Zycore" STATIC)
|
add_library("Zycore" STATIC)
|
||||||
|
target_compile_definitions("Zycore" PUBLIC "ZYCORE_STATIC_BUILD")
|
||||||
endif ()
|
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"
|
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")
|
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_set_common_flags("Zycore")
|
||||||
zyan_maybe_enable_wpo_for_lib("Zycore")
|
zyan_maybe_enable_wpo("Zycore")
|
||||||
generate_export_header("Zycore" BASE_NAME "ZYCORE" EXPORT_FILE_NAME "ZycoreExportConfig.h")
|
|
||||||
|
|
||||||
if (ZYAN_NO_LIBC)
|
if (ZYAN_NO_LIBC)
|
||||||
target_compile_definitions("Zycore" PUBLIC "ZYAN_NO_LIBC")
|
target_compile_definitions("Zycore" PUBLIC "ZYAN_NO_LIBC")
|
||||||
|
@ -148,6 +152,7 @@ target_sources("Zycore"
|
||||||
# Common
|
# Common
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/Allocator.h"
|
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/Allocator.h"
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/ArgParse.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/Bitset.h"
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/Comparison.h"
|
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/Comparison.h"
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/Defines.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/Types.h"
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/Vector.h"
|
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/Vector.h"
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/include/Zycore/Zycore.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
|
# Common
|
||||||
"src/Allocator.c"
|
"src/Allocator.c"
|
||||||
"src/ArgParse.c"
|
"src/ArgParse.c"
|
||||||
|
@ -170,17 +183,6 @@ target_sources("Zycore"
|
||||||
"src/Vector.c"
|
"src/Vector.c"
|
||||||
"src/Zycore.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)
|
if (ZYCORE_BUILD_SHARED_LIB AND WIN32)
|
||||||
target_sources("Zycore" PRIVATE "resources/VersionInfo.rc")
|
target_sources("Zycore" PRIVATE "resources/VersionInfo.rc")
|
||||||
endif ()
|
endif ()
|
||||||
|
@ -189,28 +191,51 @@ zyan_set_source_group("Zycore")
|
||||||
|
|
||||||
if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" AND NOT ZYAN_NO_LIBC)
|
if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" AND NOT ZYAN_NO_LIBC)
|
||||||
target_compile_definitions("Zycore" PRIVATE "_GNU_SOURCE")
|
target_compile_definitions("Zycore" PRIVATE "_GNU_SOURCE")
|
||||||
|
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||||
find_package(Threads REQUIRED)
|
find_package(Threads REQUIRED)
|
||||||
target_link_libraries("Zycore" Threads::Threads)
|
target_link_libraries("Zycore" Threads::Threads)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
configure_package_config_file(cmake/zycore-config.cmake.in
|
configure_package_config_file(cmake/zycore-config.cmake.in
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/zycore-config.cmake"
|
"${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
|
install(FILES
|
||||||
|
"cmake/zyan-functions.cmake"
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/zycore-config.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}
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||||
install(FILES
|
)
|
||||||
"${PROJECT_BINARY_DIR}/ZycoreExportConfig.h"
|
|
||||||
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
|
install(EXPORT "zycore-targets"
|
||||||
|
NAMESPACE "Zycore::"
|
||||||
|
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/zycore")
|
||||||
install(DIRECTORY "include/" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
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 #
|
# Developer mode #
|
||||||
# =============================================================================================== #
|
# =============================================================================================== #
|
||||||
|
@ -245,19 +270,22 @@ endif ()
|
||||||
|
|
||||||
function (zyan_add_test test)
|
function (zyan_add_test test)
|
||||||
add_executable("Test${test}" "tests/${test}.cpp")
|
add_executable("Test${test}" "tests/${test}.cpp")
|
||||||
|
target_link_libraries("Test${test}" "Zycore" "gtest")
|
||||||
if (NOT MSVC)
|
set_target_properties("Test${test}" PROPERTIES
|
||||||
target_compile_options("Test${test}" PRIVATE "-std=c++17")
|
LANGUAGE CXX
|
||||||
endif ()
|
CXX_STANDARD 17
|
||||||
|
CXX_EXTENSIONS OFF
|
||||||
target_link_libraries("Test${test}" "Zycore")
|
CXX_STANDARD_REQUIRED ON
|
||||||
target_link_libraries("Test${test}" "gtest")
|
FOLDER "Tests"
|
||||||
set_target_properties("Test${test}" PROPERTIES FOLDER "Tests")
|
)
|
||||||
target_compile_definitions("Test${test}" PRIVATE "_CRT_SECURE_NO_WARNINGS")
|
target_compile_definitions("Test${test}" PRIVATE "_CRT_SECURE_NO_WARNINGS")
|
||||||
zyan_maybe_enable_wpo("Test${test}")
|
zyan_maybe_enable_wpo("Test${test}")
|
||||||
|
add_test("${test}" "Test${test}")
|
||||||
endfunction ()
|
endfunction ()
|
||||||
|
|
||||||
if (ZYCORE_BUILD_TESTS)
|
if (ZYCORE_BUILD_TESTS)
|
||||||
|
enable_language(CXX)
|
||||||
|
enable_testing()
|
||||||
zyan_add_test("String")
|
zyan_add_test("String")
|
||||||
zyan_add_test("Vector")
|
zyan_add_test("Vector")
|
||||||
zyan_add_test("ArgParse")
|
zyan_add_test("ArgParse")
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
# Zyan Core Library for C
|
# 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.
|
Internal library providing platform independent types, macros and a fallback for environments without LibC.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
45
cmake/zyan-functions.cmake
Normal file
45
cmake/zyan-functions.cmake
Normal 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 ()
|
|
@ -2,6 +2,15 @@ set(zycore_VERSION @PROJECT_VERSION@)
|
||||||
|
|
||||||
@PACKAGE_INIT@
|
@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_INCLUDE_DIR "${PACKAGE_PREFIX_DIR}/@CMAKE_INSTALL_INCLUDEDIR@")
|
||||||
set_and_check(zycore_LIB_DIR "${PACKAGE_PREFIX_DIR}/@CMAKE_INSTALL_LIBDIR@")
|
set_and_check(zycore_LIB_DIR "${PACKAGE_PREFIX_DIR}/@CMAKE_INSTALL_LIBDIR@")
|
||||||
|
|
||||||
|
|
|
@ -98,6 +98,7 @@ static ZyanStatus PerformBasicTests(ZyanVector* vector)
|
||||||
{
|
{
|
||||||
InitTestdata(&e_v, i);
|
InitTestdata(&e_v, i);
|
||||||
ZYAN_CHECK(ZyanVectorPushBack(vector, &e_v));
|
ZYAN_CHECK(ZyanVectorPushBack(vector, &e_v));
|
||||||
|
printf("i=%d cap=%" PRIuPTR, i, vector->capacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove elements `#05..#09`
|
// Remove elements `#05..#09`
|
||||||
|
@ -332,7 +333,7 @@ static ZyanStatus TestAllocator(void)
|
||||||
// dynamic shrinking is disabled
|
// dynamic shrinking is disabled
|
||||||
ZyanVector vector;
|
ZyanVector vector;
|
||||||
ZYAN_CHECK(ZyanVectorInitEx(&vector, sizeof(TestStruct), 5, ZYAN_NULL, &allocator,
|
ZYAN_CHECK(ZyanVectorInitEx(&vector, sizeof(TestStruct), 5, ZYAN_NULL, &allocator,
|
||||||
10.0f, 0.0f));
|
10, 0));
|
||||||
|
|
||||||
static TestStruct e_v;
|
static TestStruct e_v;
|
||||||
|
|
||||||
|
|
|
@ -32,11 +32,12 @@
|
||||||
#ifndef ZYCORE_API_MEMORY_H
|
#ifndef ZYCORE_API_MEMORY_H
|
||||||
#define ZYCORE_API_MEMORY_H
|
#define ZYCORE_API_MEMORY_H
|
||||||
|
|
||||||
#include <ZycoreExportConfig.h>
|
|
||||||
#include <Zycore/Defines.h>
|
#include <Zycore/Defines.h>
|
||||||
#include <Zycore/Status.h>
|
#include <Zycore/Status.h>
|
||||||
#include <Zycore/Types.h>
|
#include <Zycore/Types.h>
|
||||||
|
|
||||||
|
#ifndef ZYAN_NO_LIBC
|
||||||
|
|
||||||
#if defined(ZYAN_WINDOWS)
|
#if defined(ZYAN_WINDOWS)
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
#elif defined(ZYAN_POSIX)
|
#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 */
|
#endif /* ZYCORE_API_MEMORY_H */
|
||||||
|
|
|
@ -32,10 +32,11 @@
|
||||||
#ifndef ZYCORE_API_PROCESS_H
|
#ifndef ZYCORE_API_PROCESS_H
|
||||||
#define ZYCORE_API_PROCESS_H
|
#define ZYCORE_API_PROCESS_H
|
||||||
|
|
||||||
#include <ZycoreExportConfig.h>
|
|
||||||
#include <Zycore/Status.h>
|
#include <Zycore/Status.h>
|
||||||
#include <Zycore/Types.h>
|
#include <Zycore/Types.h>
|
||||||
|
|
||||||
|
#ifndef ZYAN_NO_LIBC
|
||||||
|
|
||||||
/* ============================================================================================== */
|
/* ============================================================================================== */
|
||||||
/* Enums and types */
|
/* Enums and types */
|
||||||
/* ============================================================================================== */
|
/* ============================================================================================== */
|
||||||
|
@ -64,4 +65,6 @@ ZYCORE_EXPORT ZyanStatus ZyanProcessFlushInstructionCache(void* address, ZyanUSi
|
||||||
|
|
||||||
/* ============================================================================================== */
|
/* ============================================================================================== */
|
||||||
|
|
||||||
|
#endif /* ZYAN_NO_LIBC */
|
||||||
|
|
||||||
#endif /* ZYCORE_API_PROCESS_H */
|
#endif /* ZYCORE_API_PROCESS_H */
|
||||||
|
|
|
@ -32,12 +32,11 @@
|
||||||
#ifndef ZYCORE_API_SYNCHRONIZATION_H
|
#ifndef ZYCORE_API_SYNCHRONIZATION_H
|
||||||
#define ZYCORE_API_SYNCHRONIZATION_H
|
#define ZYCORE_API_SYNCHRONIZATION_H
|
||||||
|
|
||||||
#ifndef ZYAN_NO_LIBC
|
|
||||||
|
|
||||||
#include <ZycoreExportConfig.h>
|
|
||||||
#include <Zycore/Defines.h>
|
#include <Zycore/Defines.h>
|
||||||
#include <Zycore/Status.h>
|
#include <Zycore/Status.h>
|
||||||
|
|
||||||
|
#ifndef ZYAN_NO_LIBC
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -32,7 +32,6 @@
|
||||||
#ifndef ZYCORE_API_TERMINAL_H
|
#ifndef ZYCORE_API_TERMINAL_H
|
||||||
#define ZYCORE_API_TERMINAL_H
|
#define ZYCORE_API_TERMINAL_H
|
||||||
|
|
||||||
#include <ZycoreExportConfig.h>
|
|
||||||
#include <Zycore/LibC.h>
|
#include <Zycore/LibC.h>
|
||||||
#include <Zycore/Status.h>
|
#include <Zycore/Status.h>
|
||||||
|
|
||||||
|
|
|
@ -32,12 +32,11 @@
|
||||||
#ifndef ZYCORE_API_THREAD_H
|
#ifndef ZYCORE_API_THREAD_H
|
||||||
#define ZYCORE_API_THREAD_H
|
#define ZYCORE_API_THREAD_H
|
||||||
|
|
||||||
#ifndef ZYAN_NO_LIBC
|
|
||||||
|
|
||||||
#include <ZycoreExportConfig.h>
|
|
||||||
#include <Zycore/Defines.h>
|
#include <Zycore/Defines.h>
|
||||||
#include <Zycore/Status.h>
|
#include <Zycore/Status.h>
|
||||||
|
|
||||||
|
#ifndef ZYAN_NO_LIBC
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -32,7 +32,6 @@
|
||||||
#ifndef ZYCORE_ALLOCATOR_H
|
#ifndef ZYCORE_ALLOCATOR_H
|
||||||
#define ZYCORE_ALLOCATOR_H
|
#define ZYCORE_ALLOCATOR_H
|
||||||
|
|
||||||
#include <ZycoreExportConfig.h>
|
|
||||||
#include <Zycore/Status.h>
|
#include <Zycore/Status.h>
|
||||||
#include <Zycore/Types.h>
|
#include <Zycore/Types.h>
|
||||||
|
|
||||||
|
|
236
include/Zycore/Atomic.h
Normal file
236
include/Zycore/Atomic.h
Normal 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 */
|
|
@ -32,7 +32,6 @@
|
||||||
#ifndef ZYCORE_BITSET_H
|
#ifndef ZYCORE_BITSET_H
|
||||||
#define ZYCORE_BITSET_H
|
#define ZYCORE_BITSET_H
|
||||||
|
|
||||||
#include <ZycoreExportConfig.h>
|
|
||||||
#include <Zycore/Allocator.h>
|
#include <Zycore/Allocator.h>
|
||||||
#include <Zycore/Status.h>
|
#include <Zycore/Status.h>
|
||||||
#include <Zycore/Types.h>
|
#include <Zycore/Types.h>
|
||||||
|
@ -96,7 +95,7 @@ typedef ZyanStatus (*ZyanBitsetByteOperation)(ZyanU8* v1, const ZyanU8* v2);
|
||||||
* @return A zyan status code.
|
* @return A zyan status code.
|
||||||
*
|
*
|
||||||
* The space for the bitset is dynamically allocated by the default allocator using the default
|
* 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);
|
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 bitset A pointer to the `ZyanBitset` instance.
|
||||||
* @param count The initial amount of bits.
|
* @param count The initial amount of bits.
|
||||||
* @param allocator A pointer to a `ZyanAllocator` instance.
|
* @param allocator A pointer to a `ZyanAllocator` instance.
|
||||||
* @param growth_factor The growth factor (from `1.0f` to `x.xf`).
|
* @param growth_factor The growth factor.
|
||||||
* @param shrink_threshold The shrink threshold (from `0.0f` to `1.0f`).
|
* @param shrink_threshold The shrink threshold.
|
||||||
*
|
*
|
||||||
* @return A zyan status code.
|
* @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.
|
* dynamic shrinking.
|
||||||
*/
|
*/
|
||||||
ZYCORE_EXPORT ZyanStatus ZyanBitsetInitEx(ZyanBitset* bitset, ZyanUSize count,
|
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
|
* 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.
|
* @param index The bit index.
|
||||||
*
|
*
|
||||||
* @return `ZYAN_STATUS_TRUE`, if the bit is set or `ZYAN_STATUS_FALSE`, if not, Another zyan
|
* @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);
|
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.
|
* @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
|
* @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);
|
ZYCORE_EXPORT ZyanStatus ZyanBitsetTestMSB(ZyanBitset* bitset);
|
||||||
|
|
||||||
|
@ -286,7 +285,7 @@ ZYCORE_EXPORT ZyanStatus ZyanBitsetTestMSB(ZyanBitset* bitset);
|
||||||
* @param bitset A pointer to the `ZyanBitset` instance.
|
* @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
|
* @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);
|
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.
|
* @param bitset A pointer to the `ZyanBitset` instance.
|
||||||
*
|
*
|
||||||
* @return `ZYAN_STATUS_TRUE`, if all bits are set, `ZYAN_STATUS_FALSE`, if not. Another zyan
|
* @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);
|
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.
|
* @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
|
* @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);
|
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.
|
* @param bitset A pointer to the `ZyanBitset` instance.
|
||||||
*
|
*
|
||||||
* @return `ZYAN_STATUS_TRUE`, if none bits are set, `ZYAN_STATUS_FALSE`, if not. Another zyan
|
* @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);
|
ZYCORE_EXPORT ZyanStatus ZyanBitsetNone(const ZyanBitset* bitset);
|
||||||
|
|
||||||
|
|
|
@ -85,6 +85,9 @@
|
||||||
# define ZYAN_WINDOWS
|
# define ZYAN_WINDOWS
|
||||||
#elif defined(__EMSCRIPTEN__)
|
#elif defined(__EMSCRIPTEN__)
|
||||||
# define ZYAN_EMSCRIPTEN
|
# define ZYAN_EMSCRIPTEN
|
||||||
|
#elif defined(__wasi__) || defined(__WASI__)
|
||||||
|
// via: https://reviews.llvm.org/D57155
|
||||||
|
# define ZYAN_WASI
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
# define ZYAN_APPLE
|
# define ZYAN_APPLE
|
||||||
# define ZYAN_POSIX
|
# define ZYAN_POSIX
|
||||||
|
@ -131,8 +134,14 @@
|
||||||
# define ZYAN_AARCH64
|
# define ZYAN_AARCH64
|
||||||
#elif defined(_M_ARM) || defined(_M_ARMT) || defined(__arm__) || defined(__thumb__)
|
#elif defined(_M_ARM) || defined(_M_ARMT) || defined(__arm__) || defined(__thumb__)
|
||||||
# define ZYAN_ARM
|
# define ZYAN_ARM
|
||||||
#elif defined(__EMSCRIPTEN__)
|
#elif defined(__EMSCRIPTEN__) || defined(__wasm__) || defined(__WASM__)
|
||||||
// Nothing to do, `ZYAN_EMSCRIPTEN` is both platform and arch macro for this one.
|
# 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
|
#else
|
||||||
# error "Unsupported architecture detected"
|
# error "Unsupported architecture detected"
|
||||||
#endif
|
#endif
|
||||||
|
@ -157,6 +166,73 @@
|
||||||
# define ZYAN_RELEASE
|
# define ZYAN_RELEASE
|
||||||
#endif
|
#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 */
|
/* Misc compatibility macros */
|
||||||
/* ============================================================================================== */
|
/* ============================================================================================== */
|
||||||
|
@ -173,6 +249,14 @@
|
||||||
# define ZYAN_INLINE static inline
|
# define ZYAN_INLINE static inline
|
||||||
#endif
|
#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 */
|
/* Debugging and optimization macros */
|
||||||
/* ============================================================================================== */
|
/* ============================================================================================== */
|
||||||
|
@ -193,7 +277,7 @@
|
||||||
/**
|
/**
|
||||||
* Compiler-time assertion.
|
* 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)
|
# define ZYAN_STATIC_ASSERT(x) _Static_assert(x, #x)
|
||||||
#elif (defined(__cplusplus) && __cplusplus >= 201103L) || \
|
#elif (defined(__cplusplus) && __cplusplus >= 201103L) || \
|
||||||
(defined(__cplusplus) && defined (_MSC_VER) && (_MSC_VER >= 1600)) || \
|
(defined(__cplusplus) && defined (_MSC_VER) && (_MSC_VER >= 1600)) || \
|
||||||
|
@ -256,7 +340,7 @@
|
||||||
* Intentional fallthrough.
|
* Intentional fallthrough.
|
||||||
*/
|
*/
|
||||||
#if defined(ZYAN_GCC) && __GNUC__ >= 7
|
#if defined(ZYAN_GCC) && __GNUC__ >= 7
|
||||||
# define ZYAN_FALLTHROUGH __attribute__((fallthrough))
|
# define ZYAN_FALLTHROUGH ; __attribute__((__fallthrough__))
|
||||||
#else
|
#else
|
||||||
# define ZYAN_FALLTHROUGH
|
# define ZYAN_FALLTHROUGH
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -32,7 +32,6 @@
|
||||||
#ifndef ZYCORE_FORMAT_H
|
#ifndef ZYCORE_FORMAT_H
|
||||||
#define ZYCORE_FORMAT_H
|
#define ZYCORE_FORMAT_H
|
||||||
|
|
||||||
#include <ZycoreExportConfig.h>
|
|
||||||
#include <Zycore/Status.h>
|
#include <Zycore/Status.h>
|
||||||
#include <Zycore/String.h>
|
#include <Zycore/String.h>
|
||||||
#include <Zycore/Types.h>
|
#include <Zycore/Types.h>
|
||||||
|
|
117
include/Zycore/Internal/AtomicGNU.h
Normal file
117
include/Zycore/Internal/AtomicGNU.h
Normal 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 */
|
141
include/Zycore/Internal/AtomicMSVC.h
Normal file
141
include/Zycore/Internal/AtomicMSVC.h
Normal 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 */
|
|
@ -32,7 +32,6 @@
|
||||||
#ifndef ZYCORE_LIST_H
|
#ifndef ZYCORE_LIST_H
|
||||||
#define ZYCORE_LIST_H
|
#define ZYCORE_LIST_H
|
||||||
|
|
||||||
#include <ZycoreExportConfig.h>
|
|
||||||
#include <Zycore/Allocator.h>
|
#include <Zycore/Allocator.h>
|
||||||
#include <Zycore/Object.h>
|
#include <Zycore/Object.h>
|
||||||
#include <Zycore/Status.h>
|
#include <Zycore/Status.h>
|
||||||
|
|
|
@ -32,7 +32,6 @@
|
||||||
#ifndef ZYCORE_STRING_H
|
#ifndef ZYCORE_STRING_H
|
||||||
#define ZYCORE_STRING_H
|
#define ZYCORE_STRING_H
|
||||||
|
|
||||||
#include <ZycoreExportConfig.h>
|
|
||||||
#include <Zycore/Allocator.h>
|
#include <Zycore/Allocator.h>
|
||||||
#include <Zycore/Status.h>
|
#include <Zycore/Status.h>
|
||||||
#include <Zycore/Types.h>
|
#include <Zycore/Types.h>
|
||||||
|
@ -55,12 +54,12 @@ extern "C" {
|
||||||
/**
|
/**
|
||||||
* The default growth factor for all string instances.
|
* 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.
|
* 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 */
|
/* Enums and types */
|
||||||
|
@ -71,7 +70,7 @@ extern "C" {
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines the `ZyanStringFlags` datatype.
|
* Defines the `ZyanStringFlags` data-type.
|
||||||
*/
|
*/
|
||||||
typedef ZyanU8 ZyanStringFlags;
|
typedef ZyanU8 ZyanStringFlags;
|
||||||
|
|
||||||
|
@ -181,8 +180,8 @@ typedef struct ZyanStringView_
|
||||||
/* vector */ \
|
/* vector */ \
|
||||||
{ \
|
{ \
|
||||||
/* allocator */ ZYAN_NULL, \
|
/* allocator */ ZYAN_NULL, \
|
||||||
/* growth_factor */ 1.0f, \
|
/* growth_factor */ 1, \
|
||||||
/* shrink_threshold */ 0.0f, \
|
/* shrink_threshold */ 0, \
|
||||||
/* size */ sizeof(string), \
|
/* size */ sizeof(string), \
|
||||||
/* capacity */ sizeof(string), \
|
/* capacity */ sizeof(string), \
|
||||||
/* element_size */ sizeof(char), \
|
/* element_size */ sizeof(char), \
|
||||||
|
@ -213,7 +212,7 @@ typedef struct ZyanStringView_
|
||||||
* @return A zyan status code.
|
* @return A zyan status code.
|
||||||
*
|
*
|
||||||
* The memory for the string is dynamically allocated by the default allocator using the default
|
* 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
|
* The allocated buffer will be at least one character larger than the given `capacity`, to reserve
|
||||||
* space for the terminating '\0'.
|
* 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 string A pointer to the `ZyanString` instance.
|
||||||
* @param capacity The initial capacity (number of characters).
|
* @param capacity The initial capacity (number of characters).
|
||||||
* @param allocator A pointer to a `ZyanAllocator` instance.
|
* @param allocator A pointer to a `ZyanAllocator` instance.
|
||||||
* @param growth_factor The growth factor (from `1.0f` to `x.xf`).
|
* @param growth_factor The growth factor.
|
||||||
* @param shrink_threshold The shrink threshold (from `0.0f` to `1.0f`).
|
* @param shrink_threshold The shrink threshold.
|
||||||
*
|
*
|
||||||
* @return A zyan status code.
|
* @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.
|
* dynamic shrinking.
|
||||||
*
|
*
|
||||||
* The allocated buffer will be at least one character larger than the given `capacity`, to reserve
|
* 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.
|
* Finalization with `ZyanStringDestroy` is required for all strings created by this function.
|
||||||
*/
|
*/
|
||||||
ZYCORE_EXPORT ZyanStatus ZyanStringInitEx(ZyanString* string, ZyanUSize capacity,
|
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
|
* 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.
|
* 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
|
* 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
|
* The allocated buffer will be at least one character larger than the given `capacity`, to reserve
|
||||||
* space for the terminating '\0'.
|
* 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
|
* This value is automatically adjusted to the size of the source
|
||||||
* string, if a smaller value was passed.
|
* string, if a smaller value was passed.
|
||||||
* @param allocator A pointer to a `ZyanAllocator` instance.
|
* @param allocator A pointer to a `ZyanAllocator` instance.
|
||||||
* @param growth_factor The growth factor (from `1.0f` to `x.xf`).
|
* @param growth_factor The growth factor.
|
||||||
* @param shrink_threshold The shrink threshold (from `0.0f` to `1.0f`).
|
* @param shrink_threshold The shrink threshold.
|
||||||
*
|
*
|
||||||
* @return A zyan status code.
|
* @return A zyan status code.
|
||||||
*
|
*
|
||||||
* The behavior of this function is undefined, if `source` is a view into the `destination`
|
* 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.
|
* 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.
|
* dynamic shrinking.
|
||||||
*
|
*
|
||||||
* The allocated buffer will be at least one character larger than the given `capacity`, to reserve
|
* 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,
|
ZYCORE_EXPORT ZyanStatus ZyanStringDuplicateEx(ZyanString* destination,
|
||||||
const ZyanStringView* source, ZyanUSize capacity, ZyanAllocator* allocator,
|
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
|
* 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.
|
* 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
|
* 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
|
* The allocated buffer will be at least one character larger than the given `capacity`, to reserve
|
||||||
* space for the terminating '\0'.
|
* 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
|
* This value is automatically adjusted to the combined size of the
|
||||||
* source strings, if a smaller value was passed.
|
* source strings, if a smaller value was passed.
|
||||||
* @param allocator A pointer to a `ZyanAllocator` instance.
|
* @param allocator A pointer to a `ZyanAllocator` instance.
|
||||||
* @param growth_factor The growth factor (from `1.0f` to `x.xf`).
|
* @param growth_factor The growth factor.
|
||||||
* @param shrink_threshold The shrink threshold (from `0.0f` to `1.0f`).
|
* @param shrink_threshold The shrink threshold.
|
||||||
*
|
*
|
||||||
* @return A zyan status code.
|
* @return A zyan status code.
|
||||||
*
|
*
|
||||||
* The behavior of this function is undefined, if `s1` or `s2` are views into the `destination`
|
* 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.
|
* 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.
|
* dynamic shrinking.
|
||||||
*
|
*
|
||||||
* The allocated buffer will be at least one character larger than the given `capacity`, to reserve
|
* 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.
|
* Finalization with `ZyanStringDestroy` is required for all strings created by this function.
|
||||||
*/
|
*/
|
||||||
ZYCORE_EXPORT ZyanStatus ZyanStringConcatEx(ZyanString* destination, const ZyanStringView* s1,
|
ZYCORE_EXPORT ZyanStatus ZyanStringConcatEx(ZyanString* destination, const ZyanStringView* s1,
|
||||||
const ZyanStringView* s2, ZyanUSize capacity, ZyanAllocator* allocator, float growth_factor,
|
const ZyanStringView* s2, ZyanUSize capacity, ZyanAllocator* allocator, ZyanU8 growth_factor,
|
||||||
float shrink_threshold);
|
ZyanU8 shrink_threshold);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes a new `ZyanString` instance by concatenating two existing strings and
|
* 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!
|
* @warning The string is not guaranteed to be null terminated!
|
||||||
*
|
*
|
||||||
* @param string A pointer to the `ZyanStringView` instance.
|
* @param view A pointer to the `ZyanStringView` instance.
|
||||||
* @param value Receives a pointer to the C-style string.
|
* @param buffer Receives a pointer to the C-style string.
|
||||||
*
|
*
|
||||||
* @return A zyan status code.
|
* @return A zyan status code.
|
||||||
*/
|
*/
|
||||||
|
@ -741,7 +740,7 @@ ZYCORE_EXPORT ZyanStatus ZyanStringLPosI(const ZyanStringView* haystack,
|
||||||
* `index`.
|
* `index`.
|
||||||
*
|
*
|
||||||
* @return `ZYAN_STATUS_TRUE`, if the needle was found, `ZYAN_STATUS_FALSE`, if not, or another
|
* @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.
|
* 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`.
|
* `needle`.
|
||||||
*
|
*
|
||||||
* @return `ZYAN_STATUS_TRUE`, if the needle was found, `ZYAN_STATUS_FALSE`, if not, or another
|
* @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.
|
* 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`.
|
* `index`.
|
||||||
*
|
*
|
||||||
* @return `ZYAN_STATUS_TRUE`, if the needle was found, `ZYAN_STATUS_FALSE`, if not, or another
|
* @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.
|
* 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`.
|
* `needle`.
|
||||||
*
|
*
|
||||||
* @return `ZYAN_STATUS_TRUE`, if the needle was found, `ZYAN_STATUS_FALSE`, if not, or another
|
* @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.
|
* 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`.
|
* `index`.
|
||||||
*
|
*
|
||||||
* @return `ZYAN_STATUS_TRUE`, if the needle was found, `ZYAN_STATUS_FALSE`, if not, or another
|
* @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.
|
* 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`.
|
* in `s1` than in `s2`.
|
||||||
*
|
*
|
||||||
* @return `ZYAN_STATUS_TRUE`, if the strings are equal, `ZYAN_STATUS_FALSE`, if not, or another
|
* @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,
|
ZYCORE_EXPORT ZyanStatus ZyanStringCompare(const ZyanStringView* s1, const ZyanStringView* s2,
|
||||||
ZyanI32* result);
|
ZyanI32* result);
|
||||||
|
@ -861,7 +860,7 @@ ZYCORE_EXPORT ZyanStatus ZyanStringCompare(const ZyanStringView* s1, const ZyanS
|
||||||
* in `s1` than in `s2`.
|
* in `s1` than in `s2`.
|
||||||
*
|
*
|
||||||
* @return `ZYAN_STATUS_TRUE`, if the strings are equal, `ZYAN_STATUS_FALSE`, if not, or another
|
* @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,
|
ZYCORE_EXPORT ZyanStatus ZyanStringCompareI(const ZyanStringView* s1, const ZyanStringView* s2,
|
||||||
ZyanI32* result);
|
ZyanI32* result);
|
||||||
|
|
|
@ -77,6 +77,34 @@
|
||||||
# else
|
# else
|
||||||
# error "Unsupported compiler for no-libc mode."
|
# error "Unsupported compiler for no-libc mode."
|
||||||
# endif
|
# 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
|
#else
|
||||||
// If is LibC present, we use stdint types.
|
// If is LibC present, we use stdint types.
|
||||||
# include <stdint.h>
|
# include <stdint.h>
|
||||||
|
@ -93,6 +121,19 @@
|
||||||
typedef ptrdiff_t ZyanISize;
|
typedef ptrdiff_t ZyanISize;
|
||||||
typedef uintptr_t ZyanUPointer;
|
typedef uintptr_t ZyanUPointer;
|
||||||
typedef intptr_t ZyanIPointer;
|
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
|
#endif
|
||||||
|
|
||||||
// Verify size assumptions.
|
// Verify size assumptions.
|
||||||
|
@ -122,7 +163,7 @@ ZYAN_STATIC_ASSERT((ZyanI64)-1 >> 1 < (ZyanI64)((ZyanU64)-1 >> 1));
|
||||||
/**
|
/**
|
||||||
* Defines the `ZyanVoidPointer` data-type.
|
* Defines the `ZyanVoidPointer` data-type.
|
||||||
*/
|
*/
|
||||||
typedef char* ZyanVoidPointer;
|
typedef void* ZyanVoidPointer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines the `ZyanConstVoidPointer` data-type.
|
* Defines the `ZyanConstVoidPointer` data-type.
|
||||||
|
@ -139,8 +180,8 @@ typedef const void* ZyanConstVoidPointer;
|
||||||
/* Boolean */
|
/* Boolean */
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
#define ZYAN_FALSE 0
|
#define ZYAN_FALSE 0u
|
||||||
#define ZYAN_TRUE 1
|
#define ZYAN_TRUE 1u
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines the `ZyanBool` data-type.
|
* Defines the `ZyanBool` data-type.
|
||||||
|
|
|
@ -32,7 +32,6 @@
|
||||||
#ifndef ZYCORE_VECTOR_H
|
#ifndef ZYCORE_VECTOR_H
|
||||||
#define ZYCORE_VECTOR_H
|
#define ZYCORE_VECTOR_H
|
||||||
|
|
||||||
#include <ZycoreExportConfig.h>
|
|
||||||
#include <Zycore/Allocator.h>
|
#include <Zycore/Allocator.h>
|
||||||
#include <Zycore/Comparison.h>
|
#include <Zycore/Comparison.h>
|
||||||
#include <Zycore/Object.h>
|
#include <Zycore/Object.h>
|
||||||
|
@ -56,12 +55,12 @@ extern "C" {
|
||||||
/**
|
/**
|
||||||
* The default growth factor for all vector instances.
|
* 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.
|
* 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 */
|
/* Enums and types */
|
||||||
|
@ -82,11 +81,11 @@ typedef struct ZyanVector_
|
||||||
/**
|
/**
|
||||||
* The growth factor.
|
* The growth factor.
|
||||||
*/
|
*/
|
||||||
float growth_factor;
|
ZyanU8 growth_factor;
|
||||||
/**
|
/**
|
||||||
* The shrink threshold.
|
* The shrink threshold.
|
||||||
*/
|
*/
|
||||||
float shrink_threshold;
|
ZyanU8 shrink_threshold;
|
||||||
/**
|
/**
|
||||||
* The current number of elements in the vector.
|
* The current number of elements in the vector.
|
||||||
*/
|
*/
|
||||||
|
@ -123,8 +122,8 @@ typedef struct ZyanVector_
|
||||||
#define ZYAN_VECTOR_INITIALIZER \
|
#define ZYAN_VECTOR_INITIALIZER \
|
||||||
{ \
|
{ \
|
||||||
/* allocator */ ZYAN_NULL, \
|
/* allocator */ ZYAN_NULL, \
|
||||||
/* growth_factor */ 0.0f, \
|
/* growth_factor */ 0, \
|
||||||
/* shrink_threshold */ 0.0f, \
|
/* shrink_threshold */ 0, \
|
||||||
/* size */ 0, \
|
/* size */ 0, \
|
||||||
/* capacity */ 0, \
|
/* capacity */ 0, \
|
||||||
/* element_size */ 0, \
|
/* element_size */ 0, \
|
||||||
|
@ -223,7 +222,7 @@ typedef struct ZyanVector_
|
||||||
* @return A zyan status code.
|
* @return A zyan status code.
|
||||||
*
|
*
|
||||||
* The memory for the vector elements is dynamically allocated by the default allocator using the
|
* 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.
|
* 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,
|
* @param destructor A destructor callback that is invoked every time an item is deleted,
|
||||||
* or `ZYAN_NULL` if not needed.
|
* or `ZYAN_NULL` if not needed.
|
||||||
* @param allocator A pointer to a `ZyanAllocator` instance.
|
* @param allocator A pointer to a `ZyanAllocator` instance.
|
||||||
* @param growth_factor The growth factor (from `1.0f` to `x.xf`).
|
* @param growth_factor The growth factor.
|
||||||
* @param shrink_threshold The shrink threshold (from `0.0f` to `1.0f`).
|
* @param shrink_threshold The shrink threshold.
|
||||||
*
|
*
|
||||||
* @return A zyan status code.
|
* @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.
|
* dynamic shrinking.
|
||||||
*
|
*
|
||||||
* Finalization with `ZyanVectorDestroy` is required for all instances created by this function.
|
* Finalization with `ZyanVectorDestroy` is required for all instances created by this function.
|
||||||
*/
|
*/
|
||||||
ZYCORE_EXPORT ZyanStatus ZyanVectorInitEx(ZyanVector* vector, ZyanUSize element_size,
|
ZYCORE_EXPORT ZyanStatus ZyanVectorInitEx(ZyanVector* vector, ZyanUSize element_size,
|
||||||
ZyanUSize capacity, ZyanMemberProcedure destructor, ZyanAllocator* allocator,
|
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
|
* 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.
|
* @return A zyan status code.
|
||||||
*
|
*
|
||||||
* The memory for the vector is dynamically allocated by the default allocator using the default
|
* 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.
|
* 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
|
* This value is automatically adjusted to the size of the source
|
||||||
* vector, if a smaller value was passed.
|
* vector, if a smaller value was passed.
|
||||||
* @param allocator A pointer to a `ZyanAllocator` instance.
|
* @param allocator A pointer to a `ZyanAllocator` instance.
|
||||||
* @param growth_factor The growth factor (from `1.0f` to `x.xf`).
|
* @param growth_factor The growth factor.
|
||||||
* @param shrink_threshold The shrink threshold (from `0.0f` to `1.0f`).
|
* @param shrink_threshold The shrink threshold.
|
||||||
*
|
*
|
||||||
* @return A zyan status code.
|
* @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.
|
* dynamic shrinking.
|
||||||
*
|
*
|
||||||
* Finalization with `ZyanVectorDestroy` is required for all instances created by this function.
|
* Finalization with `ZyanVectorDestroy` is required for all instances created by this function.
|
||||||
*/
|
*/
|
||||||
ZYCORE_EXPORT ZyanStatus ZyanVectorDuplicateEx(ZyanVector* destination, const ZyanVector* source,
|
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
|
* 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.
|
* @param index The element index.
|
||||||
*
|
*
|
||||||
* @return A constant pointer to the desired element in the vector or `ZYAN_NULL`, if an error
|
* @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
|
* 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.
|
* 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.
|
* @param index The element index.
|
||||||
*
|
*
|
||||||
* @return A mutable pointer to the desired element in the vector or `ZYAN_NULL`, if an error
|
* @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
|
* 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.
|
* 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.
|
* @param comparison The comparison function to use.
|
||||||
*
|
*
|
||||||
* @return `ZYAN_STATUS_TRUE` if the element was found, `ZYAN_STATUS_FALSE` if not or a generic
|
* @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.
|
* 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`.
|
* @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
|
* @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.
|
* 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.
|
* @param comparison The comparison function to use.
|
||||||
*
|
*
|
||||||
* @return `ZYAN_STATUS_TRUE` if the element was found, `ZYAN_STATUS_FALSE` if not or a generic
|
* @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`
|
* 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`.
|
* 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`.
|
* @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
|
* @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`
|
* 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`.
|
* contains the index of the first entry larger than `element`.
|
||||||
|
|
|
@ -32,7 +32,6 @@
|
||||||
#ifndef ZYCORE_H
|
#ifndef ZYCORE_H
|
||||||
#define ZYCORE_H
|
#define ZYCORE_H
|
||||||
|
|
||||||
#include <ZycoreExportConfig.h>
|
|
||||||
#include <Zycore/Types.h>
|
#include <Zycore/Types.h>
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
|
@ -52,7 +51,7 @@ extern "C" {
|
||||||
/**
|
/**
|
||||||
* A macro that defines the zycore version.
|
* A macro that defines the zycore version.
|
||||||
*/
|
*/
|
||||||
#define ZYCORE_VERSION (ZyanU64)0x0001000000000000
|
#define ZYCORE_VERSION (ZyanU64)0x0001000400010000
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
/* Helper macros */
|
/* Helper macros */
|
||||||
|
|
Binary file not shown.
|
@ -26,6 +26,8 @@
|
||||||
|
|
||||||
#include <Zycore/API/Memory.h>
|
#include <Zycore/API/Memory.h>
|
||||||
|
|
||||||
|
#ifndef ZYAN_NO_LIBC
|
||||||
|
|
||||||
#if defined(ZYAN_WINDOWS)
|
#if defined(ZYAN_WINDOWS)
|
||||||
|
|
||||||
#elif defined(ZYAN_POSIX)
|
#elif defined(ZYAN_POSIX)
|
||||||
|
@ -126,3 +128,5 @@ ZyanStatus ZyanMemoryVirtualFree(void* address, ZyanUSize size)
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
/* ============================================================================================== */
|
/* ============================================================================================== */
|
||||||
|
|
||||||
|
#endif /* ZYAN_NO_LIBC */
|
||||||
|
|
|
@ -25,14 +25,21 @@
|
||||||
***************************************************************************************************/
|
***************************************************************************************************/
|
||||||
|
|
||||||
#include <Zycore/Defines.h>
|
#include <Zycore/Defines.h>
|
||||||
|
#include <Zycore/API/Process.h>
|
||||||
|
|
||||||
|
#ifndef ZYAN_NO_LIBC
|
||||||
|
|
||||||
#if defined(ZYAN_WINDOWS)
|
#if defined(ZYAN_WINDOWS)
|
||||||
|
#if defined(ZYAN_KERNEL)
|
||||||
|
# include <wdm.h>
|
||||||
|
#else
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
|
#endif
|
||||||
#elif defined(ZYAN_POSIX)
|
#elif defined(ZYAN_POSIX)
|
||||||
# include <sys/mman.h>
|
# include <sys/mman.h>
|
||||||
#else
|
#else
|
||||||
# error "Unsupported platform detected"
|
# error "Unsupported platform detected"
|
||||||
#endif
|
#endif
|
||||||
#include <Zycore/API/Process.h>
|
|
||||||
|
|
||||||
/* ============================================================================================== */
|
/* ============================================================================================== */
|
||||||
/* Exported functions */
|
/* Exported functions */
|
||||||
|
@ -66,3 +73,5 @@ ZyanStatus ZyanProcessFlushInstructionCache(void* address, ZyanUSize size)
|
||||||
/* ---------------------------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
/* ============================================================================================== */
|
/* ============================================================================================== */
|
||||||
|
|
||||||
|
#endif /* ZYAN_NO_LIBC */
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
|
|
||||||
#include <Zycore/API/Synchronization.h>
|
#include <Zycore/API/Synchronization.h>
|
||||||
|
|
||||||
|
#ifndef ZYAN_NO_LIBC
|
||||||
|
|
||||||
/* ============================================================================================== */
|
/* ============================================================================================== */
|
||||||
/* Internal functions */
|
/* Internal functions */
|
||||||
/* ============================================================================================== */
|
/* ============================================================================================== */
|
||||||
|
@ -198,3 +200,5 @@ ZyanStatus ZyanCriticalSectionDelete(ZyanCriticalSection* critical_section)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ============================================================================================== */
|
/* ============================================================================================== */
|
||||||
|
|
||||||
|
#endif /* ZYAN_NO_LIBC */
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
|
|
||||||
#include <Zycore/API/Terminal.h>
|
#include <Zycore/API/Terminal.h>
|
||||||
|
|
||||||
|
#ifndef ZYAN_NO_LIBC
|
||||||
|
|
||||||
#if defined(ZYAN_POSIX)
|
#if defined(ZYAN_POSIX)
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
#elif defined(ZYAN_WINDOWS)
|
#elif defined(ZYAN_WINDOWS)
|
||||||
|
@ -154,3 +156,5 @@ ZyanStatus ZyanTerminalIsTTY(ZyanStandardStream stream)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================================================================== */
|
/* ============================================================================================== */
|
||||||
|
|
||||||
|
#endif /* ZYAN_NO_LIBC */
|
||||||
|
|
|
@ -26,14 +26,62 @@
|
||||||
|
|
||||||
#include <Zycore/API/Thread.h>
|
#include <Zycore/API/Thread.h>
|
||||||
|
|
||||||
|
#ifndef ZYAN_NO_LIBC
|
||||||
|
|
||||||
/* ============================================================================================== */
|
/* ============================================================================================== */
|
||||||
/* Internal functions */
|
/* 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
|
||||||
|
|
||||||
/* ============================================================================================== */
|
/* ============================================================================================== */
|
||||||
|
|
||||||
|
#endif /* ZYAN_NO_LIBC */
|
||||||
|
|
|
@ -31,8 +31,8 @@
|
||||||
/* Internal constants */
|
/* Internal constants */
|
||||||
/* ============================================================================================== */
|
/* ============================================================================================== */
|
||||||
|
|
||||||
#define ZYAN_BITSET_GROWTH_FACTOR 2.00f
|
#define ZYAN_BITSET_GROWTH_FACTOR 2
|
||||||
#define ZYAN_BITSET_SHRINK_THRESHOLD 0.50f
|
#define ZYAN_BITSET_SHRINK_THRESHOLD 2
|
||||||
|
|
||||||
/* ============================================================================================== */
|
/* ============================================================================================== */
|
||||||
/* Internal macros */
|
/* Internal macros */
|
||||||
|
@ -56,7 +56,7 @@
|
||||||
* @return The amount of bytes needed to fit `x` bits.
|
* @return The amount of bytes needed to fit `x` bits.
|
||||||
*/
|
*/
|
||||||
#define ZYAN_BITSET_BITS_TO_BYTES(x) \
|
#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.
|
* Returns the offset of the given bit.
|
||||||
|
@ -140,7 +140,7 @@ ZyanStatus ZyanBitsetInit(ZyanBitset* bitset, ZyanUSize count)
|
||||||
#endif // ZYAN_NO_LIBC
|
#endif // ZYAN_NO_LIBC
|
||||||
|
|
||||||
ZyanStatus ZyanBitsetInitEx(ZyanBitset* bitset, ZyanUSize count, ZyanAllocator* allocator,
|
ZyanStatus ZyanBitsetInitEx(ZyanBitset* bitset, ZyanUSize count, ZyanAllocator* allocator,
|
||||||
float growth_factor, float shrink_threshold)
|
ZyanU8 growth_factor, ZyanU8 shrink_threshold)
|
||||||
{
|
{
|
||||||
if (!bitset)
|
if (!bitset)
|
||||||
{
|
{
|
||||||
|
|
|
@ -83,7 +83,7 @@ static const ZyanStringView STR_SUB = ZYAN_DEFINE_STRING_VIEW("-");
|
||||||
/* Decimal */
|
/* 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)
|
ZyanStatus ZyanStringAppendDecU32(ZyanString* string, ZyanU32 value, ZyanU8 padding_length)
|
||||||
{
|
{
|
||||||
if (!string)
|
if (!string)
|
||||||
|
@ -179,7 +179,7 @@ ZyanStatus ZyanStringAppendDecU64(ZyanString* string, ZyanU64 value, ZyanU8 padd
|
||||||
/* Hexadecimal */
|
/* 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,
|
ZyanStatus ZyanStringAppendHexU32(ZyanString* string, ZyanU32 value, ZyanU8 padding_length,
|
||||||
ZyanBool uppercase)
|
ZyanBool uppercase)
|
||||||
{
|
{
|
||||||
|
@ -423,7 +423,7 @@ ZyanStatus ZyanStringAppendFormat(ZyanString* string, const char* format, ...)
|
||||||
|
|
||||||
ZyanStatus ZyanStringAppendDecU(ZyanString* string, ZyanU64 value, ZyanU8 padding_length)
|
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);
|
return ZyanStringAppendDecU64(string, value, padding_length);
|
||||||
#else
|
#else
|
||||||
// Working with 64-bit values is slow on non 64-bit systems
|
// 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,
|
ZyanStatus ZyanStringAppendHexU(ZyanString* string, ZyanU64 value, ZyanU8 padding_length,
|
||||||
ZyanBool uppercase)
|
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);
|
return ZyanStringAppendHexU64(string, value, padding_length, uppercase);
|
||||||
#else
|
#else
|
||||||
// Working with 64-bit values is slow on non 64-bit systems
|
// Working with 64-bit values is slow on non 64-bit systems
|
||||||
|
|
|
@ -62,7 +62,7 @@ ZyanStatus ZyanStringInit(ZyanString* string, ZyanUSize capacity)
|
||||||
#endif // ZYAN_NO_LIBC
|
#endif // ZYAN_NO_LIBC
|
||||||
|
|
||||||
ZyanStatus ZyanStringInitEx(ZyanString* string, ZyanUSize capacity, ZyanAllocator* allocator,
|
ZyanStatus ZyanStringInitEx(ZyanString* string, ZyanUSize capacity, ZyanAllocator* allocator,
|
||||||
float growth_factor, float shrink_threshold)
|
ZyanU8 growth_factor, ZyanU8 shrink_threshold)
|
||||||
{
|
{
|
||||||
if (!string)
|
if (!string)
|
||||||
{
|
{
|
||||||
|
@ -133,7 +133,7 @@ ZyanStatus ZyanStringDuplicate(ZyanString* destination, const ZyanStringView* so
|
||||||
#endif // ZYAN_NO_LIBC
|
#endif // ZYAN_NO_LIBC
|
||||||
|
|
||||||
ZyanStatus ZyanStringDuplicateEx(ZyanString* destination, const ZyanStringView* source,
|
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)
|
if (!source || !source->string.vector.size)
|
||||||
{
|
{
|
||||||
|
@ -194,8 +194,8 @@ ZyanStatus ZyanStringConcat(ZyanString* destination, const ZyanStringView* s1,
|
||||||
#endif // ZYAN_NO_LIBC
|
#endif // ZYAN_NO_LIBC
|
||||||
|
|
||||||
ZyanStatus ZyanStringConcatEx(ZyanString* destination, const ZyanStringView* s1,
|
ZyanStatus ZyanStringConcatEx(ZyanString* destination, const ZyanStringView* s1,
|
||||||
const ZyanStringView* s2, ZyanUSize capacity, ZyanAllocator* allocator, float growth_factor,
|
const ZyanStringView* s2, ZyanUSize capacity, ZyanAllocator* allocator, ZyanU8 growth_factor,
|
||||||
float shrink_threshold)
|
ZyanU8 shrink_threshold)
|
||||||
{
|
{
|
||||||
if (!s1 || !s2 || !s1->string.vector.size || !s2->string.vector.size)
|
if (!s1 || !s2 || !s1->string.vector.size || !s2->string.vector.size)
|
||||||
{
|
{
|
||||||
|
|
28
src/Vector.c
28
src/Vector.c
|
@ -52,7 +52,7 @@
|
||||||
* @return `ZYAN_TRUE`, if the vector should shrink or `ZYAN_FALSE`, if not.
|
* @return `ZYAN_TRUE`, if the vector should shrink or `ZYAN_FALSE`, if not.
|
||||||
*/
|
*/
|
||||||
#define ZYCORE_VECTOR_SHOULD_SHRINK(size, capacity, threshold) \
|
#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`.
|
* 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
|
* Shifts all elements starting at the specified `index` by the amount of `count` to the left.
|
||||||
* `count` to the left.
|
|
||||||
*
|
*
|
||||||
* @param vector A pointer to the `ZyanVector` instance.
|
* @param vector A pointer to the `ZyanVector` instance.
|
||||||
* @param index The start index.
|
* @param index The start index.
|
||||||
|
@ -136,7 +135,7 @@ static ZyanStatus ZyanVectorShiftLeft(ZyanVector* vector, ZyanUSize index, ZyanU
|
||||||
ZYAN_ASSERT(count > 0);
|
ZYAN_ASSERT(count > 0);
|
||||||
//ZYAN_ASSERT((ZyanISize)count - (ZyanISize)index + 1 >= 0);
|
//ZYAN_ASSERT((ZyanISize)count - (ZyanISize)index + 1 >= 0);
|
||||||
|
|
||||||
void* const source = ZYCORE_VECTOR_OFFSET(vector, index + count);
|
const void* const source = ZYCORE_VECTOR_OFFSET(vector, index + count);
|
||||||
void* const dest = ZYCORE_VECTOR_OFFSET(vector, index);
|
void* const dest = ZYCORE_VECTOR_OFFSET(vector, index);
|
||||||
const ZyanUSize size = (vector->size - index - count) * vector->element_size;
|
const ZyanUSize size = (vector->size - index - count) * vector->element_size;
|
||||||
ZYAN_MEMMOVE(dest, source, size);
|
ZYAN_MEMMOVE(dest, source, size);
|
||||||
|
@ -145,8 +144,7 @@ static ZyanStatus ZyanVectorShiftLeft(ZyanVector* vector, ZyanUSize index, ZyanU
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shifts all elements starting at the specified `index` by the amount of
|
* Shifts all elements starting at the specified `index` by the amount of `count` to the right.
|
||||||
* `count` to the right.
|
|
||||||
*
|
*
|
||||||
* @param vector A pointer to the `ZyanVector` instance.
|
* @param vector A pointer to the `ZyanVector` instance.
|
||||||
* @param index The start index.
|
* @param index The start index.
|
||||||
|
@ -162,7 +160,7 @@ static ZyanStatus ZyanVectorShiftRight(ZyanVector* vector, ZyanUSize index, Zyan
|
||||||
ZYAN_ASSERT(count > 0);
|
ZYAN_ASSERT(count > 0);
|
||||||
ZYAN_ASSERT(vector->size + count <= vector->capacity);
|
ZYAN_ASSERT(vector->size + count <= vector->capacity);
|
||||||
|
|
||||||
void* const source = ZYCORE_VECTOR_OFFSET(vector, index);
|
const void* const source = ZYCORE_VECTOR_OFFSET(vector, index);
|
||||||
void* const dest = ZYCORE_VECTOR_OFFSET(vector, index + count);
|
void* const dest = ZYCORE_VECTOR_OFFSET(vector, index + count);
|
||||||
const ZyanUSize size = (vector->size - index) * vector->element_size;
|
const ZyanUSize size = (vector->size - index) * vector->element_size;
|
||||||
ZYAN_MEMMOVE(dest, source, size);
|
ZYAN_MEMMOVE(dest, source, size);
|
||||||
|
@ -192,11 +190,10 @@ ZyanStatus ZyanVectorInit(ZyanVector* vector, ZyanUSize element_size, ZyanUSize
|
||||||
#endif // ZYAN_NO_LIBC
|
#endif // ZYAN_NO_LIBC
|
||||||
|
|
||||||
ZyanStatus ZyanVectorInitEx(ZyanVector* vector, ZyanUSize element_size, ZyanUSize capacity,
|
ZyanStatus ZyanVectorInitEx(ZyanVector* vector, ZyanUSize element_size, ZyanUSize capacity,
|
||||||
ZyanMemberProcedure destructor, ZyanAllocator* allocator, float growth_factor,
|
ZyanMemberProcedure destructor, ZyanAllocator* allocator, ZyanU8 growth_factor,
|
||||||
float shrink_threshold)
|
ZyanU8 shrink_threshold)
|
||||||
{
|
{
|
||||||
if (!vector || !element_size || !allocator || (growth_factor < 1.0f) ||
|
if (!vector || !element_size || !allocator || (growth_factor < 1))
|
||||||
(shrink_threshold < 0.0f) || (shrink_threshold > 1.0f))
|
|
||||||
{
|
{
|
||||||
return ZYAN_STATUS_INVALID_ARGUMENT;
|
return ZYAN_STATUS_INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
@ -225,8 +222,8 @@ ZyanStatus ZyanVectorInitCustomBuffer(ZyanVector* vector, ZyanUSize element_size
|
||||||
}
|
}
|
||||||
|
|
||||||
vector->allocator = ZYAN_NULL;
|
vector->allocator = ZYAN_NULL;
|
||||||
vector->growth_factor = 1.0f;
|
vector->growth_factor = 1;
|
||||||
vector->shrink_threshold = 0.0f;
|
vector->shrink_threshold = 0;
|
||||||
vector->size = 0;
|
vector->size = 0;
|
||||||
vector->capacity = capacity;
|
vector->capacity = capacity;
|
||||||
vector->element_size = element_size;
|
vector->element_size = element_size;
|
||||||
|
@ -281,7 +278,7 @@ ZyanStatus ZyanVectorDuplicate(ZyanVector* destination, const ZyanVector* source
|
||||||
#endif // ZYAN_NO_LIBC
|
#endif // ZYAN_NO_LIBC
|
||||||
|
|
||||||
ZyanStatus ZyanVectorDuplicateEx(ZyanVector* destination, const ZyanVector* source,
|
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)
|
if (!source)
|
||||||
{
|
{
|
||||||
|
@ -774,8 +771,9 @@ ZyanStatus ZyanVectorResizeEx(ZyanVector* vector, ZyanUSize size, const void* in
|
||||||
if (ZYCORE_VECTOR_SHOULD_GROW(size, vector->capacity) ||
|
if (ZYCORE_VECTOR_SHOULD_GROW(size, vector->capacity) ||
|
||||||
ZYCORE_VECTOR_SHOULD_SHRINK(size, vector->capacity, vector->shrink_threshold))
|
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)));
|
ZYAN_CHECK(ZyanVectorReallocate(vector, (ZyanUSize)(size * vector->growth_factor)));
|
||||||
};
|
}
|
||||||
|
|
||||||
if (initializer && (size > vector->size))
|
if (initializer && (size > vector->size))
|
||||||
{
|
{
|
||||||
|
|
|
@ -146,8 +146,8 @@ TEST(VectorTest, InitBasic)
|
||||||
ASSERT_EQ(ZyanVectorInit(&vector, sizeof(ZyanU64), 0,
|
ASSERT_EQ(ZyanVectorInit(&vector, sizeof(ZyanU64), 0,
|
||||||
reinterpret_cast<ZyanMemberProcedure>(ZYAN_NULL)), ZYAN_STATUS_SUCCESS);
|
reinterpret_cast<ZyanMemberProcedure>(ZYAN_NULL)), ZYAN_STATUS_SUCCESS);
|
||||||
EXPECT_EQ(vector.allocator, ZyanAllocatorDefault());
|
EXPECT_EQ(vector.allocator, ZyanAllocatorDefault());
|
||||||
EXPECT_FLOAT_EQ(vector.growth_factor, ZYAN_VECTOR_DEFAULT_GROWTH_FACTOR);
|
EXPECT_EQ(vector.growth_factor, ZYAN_VECTOR_DEFAULT_GROWTH_FACTOR);
|
||||||
EXPECT_FLOAT_EQ(vector.shrink_threshold, ZYAN_VECTOR_DEFAULT_SHRINK_THRESHOLD);
|
EXPECT_EQ(vector.shrink_threshold, ZYAN_VECTOR_DEFAULT_SHRINK_THRESHOLD);
|
||||||
EXPECT_EQ(vector.size, static_cast<ZyanUSize>(0));
|
EXPECT_EQ(vector.size, static_cast<ZyanUSize>(0));
|
||||||
EXPECT_EQ(vector.capacity, static_cast<ZyanUSize>(ZYAN_VECTOR_MIN_CAPACITY));
|
EXPECT_EQ(vector.capacity, static_cast<ZyanUSize>(ZYAN_VECTOR_MIN_CAPACITY));
|
||||||
EXPECT_EQ(vector.element_size, sizeof(ZyanU64));
|
EXPECT_EQ(vector.element_size, sizeof(ZyanU64));
|
||||||
|
@ -166,11 +166,11 @@ TEST(VectorTest, InitAdvanced)
|
||||||
ZyanVector vector;
|
ZyanVector vector;
|
||||||
|
|
||||||
ASSERT_EQ(ZyanVectorInitEx(&vector, sizeof(ZyanU16), 0,
|
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);
|
ZYAN_STATUS_SUCCESS);
|
||||||
EXPECT_EQ(vector.allocator, ZyanAllocatorDefault());
|
EXPECT_EQ(vector.allocator, ZyanAllocatorDefault());
|
||||||
EXPECT_FLOAT_EQ(vector.growth_factor, 1.0f);
|
EXPECT_EQ(vector.growth_factor, 1);
|
||||||
EXPECT_FLOAT_EQ(vector.shrink_threshold, 0.0f);
|
EXPECT_EQ(vector.shrink_threshold, 0);
|
||||||
EXPECT_EQ(vector.size, static_cast<ZyanUSize>(0));
|
EXPECT_EQ(vector.size, static_cast<ZyanUSize>(0));
|
||||||
EXPECT_EQ(vector.capacity, static_cast<ZyanUSize>(ZYAN_VECTOR_MIN_CAPACITY));
|
EXPECT_EQ(vector.capacity, static_cast<ZyanUSize>(ZYAN_VECTOR_MIN_CAPACITY));
|
||||||
EXPECT_EQ(vector.element_size, sizeof(ZyanU16));
|
EXPECT_EQ(vector.element_size, sizeof(ZyanU16));
|
||||||
|
@ -179,7 +179,7 @@ TEST(VectorTest, InitAdvanced)
|
||||||
|
|
||||||
// Custom capacity
|
// Custom capacity
|
||||||
EXPECT_EQ(ZyanVectorInitEx(&vector, sizeof(ZyanU16), 10,
|
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);
|
ZYAN_STATUS_SUCCESS);
|
||||||
EXPECT_EQ(vector.capacity, static_cast<ZyanUSize>(ZYAN_MAX(ZYAN_VECTOR_MIN_CAPACITY, 10)));
|
EXPECT_EQ(vector.capacity, static_cast<ZyanUSize>(ZYAN_MAX(ZYAN_VECTOR_MIN_CAPACITY, 10)));
|
||||||
EXPECT_EQ(ZyanVectorDestroy(&vector), ZYAN_STATUS_SUCCESS);
|
EXPECT_EQ(ZyanVectorDestroy(&vector), ZYAN_STATUS_SUCCESS);
|
||||||
|
@ -196,8 +196,8 @@ TEST(VectorTest, InitCustomBuffer)
|
||||||
ZYAN_ARRAY_LENGTH(buffer), reinterpret_cast<ZyanMemberProcedure>(ZYAN_NULL)),
|
ZYAN_ARRAY_LENGTH(buffer), reinterpret_cast<ZyanMemberProcedure>(ZYAN_NULL)),
|
||||||
ZYAN_STATUS_SUCCESS);
|
ZYAN_STATUS_SUCCESS);
|
||||||
EXPECT_EQ(vector.allocator, ZYAN_NULL);
|
EXPECT_EQ(vector.allocator, ZYAN_NULL);
|
||||||
EXPECT_FLOAT_EQ(vector.growth_factor, 1.0f);
|
EXPECT_EQ(vector.growth_factor, 1);
|
||||||
EXPECT_FLOAT_EQ(vector.shrink_threshold, 0.0f);
|
EXPECT_EQ(vector.shrink_threshold, 0);
|
||||||
EXPECT_EQ(vector.size, static_cast<ZyanUSize>(0));
|
EXPECT_EQ(vector.size, static_cast<ZyanUSize>(0));
|
||||||
EXPECT_EQ(vector.capacity, ZYAN_ARRAY_LENGTH(buffer));
|
EXPECT_EQ(vector.capacity, ZYAN_ARRAY_LENGTH(buffer));
|
||||||
EXPECT_EQ(vector.element_size, sizeof(ZyanU16));
|
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)
|
TEST_P(VectorTestFilled, ElementAccess)
|
||||||
{
|
{
|
||||||
static const ZyanU64 element_in = 1337;
|
static const ZyanU64 element_in = 1337;
|
||||||
|
|
Loading…
Reference in a new issue