diff --git a/.gitmodules b/.gitmodules index 4433891..e69de29 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +0,0 @@ -[submodule "ThirdParty/simdutf"] - path = ThirdParty/simdutf - url = https://github.com/simdutf/simdutf.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 9df8af1..1c81c57 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,8 +1,18 @@ cmake_minimum_required (VERSION 3.20) +include(cmake/prelude.cmake) include(CMakeDependentOption) +include(FetchContent) -project ("simstr") -set (CMAKE_CXX_STANDARD 20) +project ( + simstr + VERSION 1.0.0 + DESCRIPTION "Yet another string library" + HOMEPAGE_URL "https://snegopat.ru/simstr" + LANGUAGES CXX +) + +include(cmake/project-is-top-level.cmake) +include(cmake/variables.cmake) if (${CMAKE_CXX_COMPILER_ID} STREQUAL MSVC) set (MSVC_COMPILER ON) @@ -29,29 +39,57 @@ if (EMSCRIPTEN) endif() endif(EMSCRIPTEN) -set (SIMDUTF_TOOLS OFF) -set (SIMDUTF_TESTS OFF) -add_subdirectory(ThirdParty/simdutf) - -include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include") - -add_library(simstr +add_library(simstr_simstr src/sstring.cpp src/simple_unicode.cpp ) +add_library(simstr::simstr ALIAS simstr_simstr) -target_link_libraries(simstr PUBLIC simdutf) +target_include_directories( + simstr_simstr ${warning_guard} + PUBLIC + "\$" +) + +target_compile_features(simstr_simstr PUBLIC cxx_std_20) + +set_target_properties( + simstr_simstr PROPERTIES + CXX_VISIBILITY_PRESET hidden + VISIBILITY_INLINES_HIDDEN YES + VERSION "${PROJECT_VERSION}" + SOVERSION "${PROJECT_VERSION_MAJOR}" + EXPORT_NAME simstr + OUTPUT_NAME simstr +) + +function (Simdutf) + set (SIMDUTF_TOOLS OFF) + set (SIMDUTF_TESTS OFF) + set (SIMDUTF_BENCHMARKS OFF) + FetchContent_Declare( + simdutf + GIT_REPOSITORY git@github.com:simdutf/simdutf.git + GIT_SHALLOW TRUE + GIT_TAG tags/v7.5.0 + FIND_PACKAGE_ARGS + ) + FetchContent_MakeAvailable(simdutf) +endfunction() + +Simdutf() + +target_link_libraries(simstr_simstr PUBLIC simdutf::simdutf) if (SIMSTR_SHARED) add_compile_definitions(SIMSTR_SHARED) - target_compile_definitions(simstr PRIVATE SIMSTR_EXPORT) + target_compile_definitions(simstr_simstr PRIVATE SIMSTR_EXPORT) endif(SIMSTR_SHARED) if (SIMSTR_BUILD_TESTS) enable_testing() set (BUILD_TESTS ON) # Load and build GTest - include(FetchContent) FetchContent_Declare( googletest # Specify the commit you depend on and update it regularly. @@ -88,3 +126,22 @@ if (SIMSTR_BENCHMARKS)# AND CMAKE_BUILD_TYPE STREQUAL Release) GBencmark() add_subdirectory(bench) endif () + +# ---- Install rules ---- + +if(NOT CMAKE_SKIP_INSTALL_RULES) + include(cmake/install-rules.cmake) +endif() + +# ---- Developer mode ---- + +if(NOT simstr_DEVELOPER_MODE) + return() +elseif(NOT PROJECT_IS_TOP_LEVEL) + message( + AUTHOR_WARNING + "Developer mode is intended for developers of simstr" + ) +endif() + +include(cmake/dev-mode.cmake) diff --git a/ThirdParty/simdutf b/ThirdParty/simdutf deleted file mode 160000 index dd192d6..0000000 --- a/ThirdParty/simdutf +++ /dev/null @@ -1 +0,0 @@ -Subproject commit dd192d6fc5fdf0ad21c0759cd3133bbcc7ae4122 diff --git a/bench/CMakeLists.txt b/bench/CMakeLists.txt index 7932b20..ee2797a 100644 --- a/bench/CMakeLists.txt +++ b/bench/CMakeLists.txt @@ -4,10 +4,10 @@ cmake_minimum_required (VERSION 3.15) add_executable(benchStr bench_str.cpp bench.h) -target_link_libraries(benchStr simstr benchmark::benchmark benchmark::benchmark_main) +target_link_libraries(benchStr simstr_simstr benchmark::benchmark benchmark::benchmark_main) add_executable(process_result process_result.cpp) -target_link_libraries(process_result simstr) +target_link_libraries(process_result simstr_simstr) if (EMSCRIPTEN) #target_link_options(benchStr PRIVATE -sSTACK_SIZE=1048576 -sINITIAL_MEMORY=128MB -sALLOW_MEMORY_GROWTH=0) diff --git a/cmake/dev-mode.cmake b/cmake/dev-mode.cmake new file mode 100644 index 0000000..0011f5c --- /dev/null +++ b/cmake/dev-mode.cmake @@ -0,0 +1,21 @@ +include(cmake/folders.cmake) + +include(CTest) +if(BUILD_TESTING) + add_subdirectory(test) +endif() + +option(BUILD_MCSS_DOCS "Build documentation using Doxygen and m.css" OFF) +if(BUILD_MCSS_DOCS) + include(cmake/docs.cmake) +endif() + +option(ENABLE_COVERAGE "Enable coverage support separate from CTest's" OFF) +if(ENABLE_COVERAGE) + include(cmake/coverage.cmake) +endif() + +include(cmake/lint-targets.cmake) +include(cmake/spell-targets.cmake) + +add_folders(Project) diff --git a/cmake/install-config.cmake b/cmake/install-config.cmake new file mode 100644 index 0000000..2e23333 --- /dev/null +++ b/cmake/install-config.cmake @@ -0,0 +1 @@ +include("${CMAKE_CURRENT_LIST_DIR}/simstrTargets.cmake") diff --git a/cmake/install-rules.cmake b/cmake/install-rules.cmake new file mode 100644 index 0000000..e40bbc5 --- /dev/null +++ b/cmake/install-rules.cmake @@ -0,0 +1,71 @@ +if(PROJECT_IS_TOP_LEVEL) + set( + CMAKE_INSTALL_INCLUDEDIR "include/simstr-${PROJECT_VERSION}" + CACHE STRING "" + ) + set_property(CACHE CMAKE_INSTALL_INCLUDEDIR PROPERTY TYPE PATH) +endif() + +include(CMakePackageConfigHelpers) +include(GNUInstallDirs) + +# find_package() call for consumers to find this project +set(package simstr) + +install( + DIRECTORY + include/ + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" + COMPONENT simstr_Development +) + +install( + TARGETS simstr_simstr + EXPORT simstrTargets + RUNTIME # + COMPONENT simstr_Runtime + LIBRARY # + COMPONENT simstr_Runtime + NAMELINK_COMPONENT simstr_Development + ARCHIVE # + COMPONENT simstr_Development + INCLUDES # + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" +) + +write_basic_package_version_file( + "${package}ConfigVersion.cmake" + COMPATIBILITY SameMajorVersion +) + +# Allow package maintainers to freely override the path for the configs +set( + simstr_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/${package}" + CACHE STRING "CMake package config location relative to the install prefix" +) +set_property(CACHE simstr_INSTALL_CMAKEDIR PROPERTY TYPE PATH) +mark_as_advanced(simstr_INSTALL_CMAKEDIR) + +install( + FILES cmake/install-config.cmake + DESTINATION "${simstr_INSTALL_CMAKEDIR}" + RENAME "${package}Config.cmake" + COMPONENT simstr_Development +) + +install( + FILES "${PROJECT_BINARY_DIR}/${package}ConfigVersion.cmake" + DESTINATION "${simstr_INSTALL_CMAKEDIR}" + COMPONENT simstr_Development +) + +install( + EXPORT simstrTargets + NAMESPACE simstr:: + DESTINATION "${simstr_INSTALL_CMAKEDIR}" + COMPONENT simstr_Development +) + +if(PROJECT_IS_TOP_LEVEL) + include(CPack) +endif() diff --git a/cmake/prelude.cmake b/cmake/prelude.cmake new file mode 100644 index 0000000..c37d590 --- /dev/null +++ b/cmake/prelude.cmake @@ -0,0 +1,10 @@ +# ---- In-source guard ---- + +if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR) + message( + FATAL_ERROR + "In-source builds are not supported. " + "Please read the BUILDING document before trying to build this project. " + "You may need to delete 'CMakeCache.txt' and 'CMakeFiles/' first." + ) +endif() diff --git a/cmake/project-is-top-level.cmake b/cmake/project-is-top-level.cmake new file mode 100644 index 0000000..3435fc0 --- /dev/null +++ b/cmake/project-is-top-level.cmake @@ -0,0 +1,6 @@ +# This variable is set by project() in CMake 3.21+ +string( + COMPARE EQUAL + "${CMAKE_SOURCE_DIR}" "${PROJECT_SOURCE_DIR}" + PROJECT_IS_TOP_LEVEL +) diff --git a/cmake/variables.cmake b/cmake/variables.cmake new file mode 100644 index 0000000..fbc248f --- /dev/null +++ b/cmake/variables.cmake @@ -0,0 +1,41 @@ +# ---- Developer mode ---- + +# Developer mode enables targets and code paths in the CMake scripts that are +# only relevant for the developer(s) of simstr +# Targets necessary to build the project must be provided unconditionally, so +# consumers can trivially build and package the project +if(PROJECT_IS_TOP_LEVEL) + option(simstr_DEVELOPER_MODE "Enable developer mode" OFF) + option(BUILD_SHARED_LIBS "Build shared libs." OFF) +endif() + +# ---- Suppress C4251 on Windows ---- + +# Please see include/simstr/simstr.hpp for more details +set(pragma_suppress_c4251 " +/* This needs to suppress only for MSVC */ +#if defined(_MSC_VER) && !defined(__ICL) +# define SIMSTR_SUPPRESS_C4251 _Pragma(\"warning(suppress:4251)\") +#else +# define SIMSTR_SUPPRESS_C4251 +#endif +") + +# ---- Warning guard ---- + +# target_include_directories with the SYSTEM modifier will request the compiler +# to omit warnings from the provided paths, if the compiler supports that +# This is to provide a user experience similar to find_package when +# add_subdirectory or FetchContent is used to consume this project +set(warning_guard "") +if(NOT PROJECT_IS_TOP_LEVEL) + option( + simstr_INCLUDES_WITH_SYSTEM + "Use SYSTEM modifier for simstr's includes, disabling warnings" + ON + ) + mark_as_advanced(simstr_INCLUDES_WITH_SYSTEM) + if(simstr_INCLUDES_WITH_SYSTEM) + set(warning_guard SYSTEM) + endif() +endif() diff --git a/include/simstr/sstring.h b/include/simstr/sstring.h index b8a6246..df5b9c4 100644 --- a/include/simstr/sstring.h +++ b/include/simstr/sstring.h @@ -641,7 +641,8 @@ public: * ``` */ constexpr str_piece operator()(ptrdiff_t from, ptrdiff_t len = 0) const noexcept { - size_t myLen = _len(), idxStart = from >= 0 ? from : myLen + from, idxEnd = len > 0 ? idxStart + len : myLen > -len ? myLen + len : 0; + size_t myLen = _len(), idxStart = from >= 0 ? from : myLen > -from ? myLen + from : 0, + idxEnd = len > 0 ? idxStart + len : myLen > -len ? myLen + len : 0; if (idxEnd > myLen) idxEnd = myLen; if (idxStart > idxEnd) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 331b9f6..679f25f 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -3,7 +3,7 @@ # add_executable(testStr test_str.cpp) -target_link_libraries(testStr simstr gtest_main) +target_link_libraries(testStr simstr_simstr gtest_main) add_test(NAME testStr COMMAND testStr) if (EMSCRIPTEN)