Skip to content

Commit daf4fe5

Browse files
authored
Implement a Decimal numeric module powered by mpdecimal (#2030)
Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>
1 parent 596a6f7 commit daf4fe5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+21792
-1
lines changed

.github/workflows/website-build.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ jobs:
1818
-DCMAKE_BUILD_TYPE:STRING=Release
1919
-DSOURCEMETA_CORE_LANG_IO:BOOL=OFF
2020
-DSOURCEMETA_CORE_LANG_PROCESS:BOOL=OFF
21+
-DSOURCEMETA_CORE_LANG_PARALLEL:BOOL=OFF
22+
-DSOURCEMETA_CORE_LANG_NUMERIC:BOOL=OFF
2123
-DSOURCEMETA_CORE_TIME:BOOL=OFF
2224
-DSOURCEMETA_CORE_UUID:BOOL=OFF
2325
-DSOURCEMETA_CORE_REGEX:BOOL=OFF

.github/workflows/website-deploy.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ jobs:
2828
-DCMAKE_BUILD_TYPE:STRING=Release
2929
-DSOURCEMETA_CORE_LANG_IO:BOOL=OFF
3030
-DSOURCEMETA_CORE_LANG_PROCESS:BOOL=OFF
31+
-DSOURCEMETA_CORE_LANG_PARALLEL:BOOL=OFF
32+
-DSOURCEMETA_CORE_LANG_NUMERIC:BOOL=OFF
3133
-DSOURCEMETA_CORE_TIME:BOOL=OFF
3234
-DSOURCEMETA_CORE_UUID:BOOL=OFF
3335
-DSOURCEMETA_CORE_REGEX:BOOL=OFF

CMakeLists.txt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
cmake_minimum_required(VERSION 3.16)
2-
project(core VERSION 0.0.0 LANGUAGES C CXX DESCRIPTION "Sourcemeta Core")
2+
project(core VERSION 0.0.0 LANGUAGES C CXX ASM_MASM DESCRIPTION "Sourcemeta Core")
33
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
44

55
# Options
66
option(SOURCEMETA_CORE_LANG_IO "Build the Sourcemeta Core language I/O library" ON)
77
option(SOURCEMETA_CORE_LANG_PROCESS "Build the Sourcemeta Core language Process library" ON)
88
option(SOURCEMETA_CORE_LANG_PARALLEL "Build the Sourcemeta Core language parallel library" ON)
9+
option(SOURCEMETA_CORE_LANG_NUMERIC "Build the Sourcemeta Core language numeric library" ON)
910
option(SOURCEMETA_CORE_TIME "Build the Sourcemeta Core time library" ON)
1011
option(SOURCEMETA_CORE_UUID "Build the Sourcemeta Core UUID library" ON)
1112
option(SOURCEMETA_CORE_MD5 "Build the Sourcemeta Core MD5 library" ON)
@@ -68,6 +69,11 @@ if(SOURCEMETA_CORE_LANG_PARALLEL)
6869
add_subdirectory(src/lang/parallel)
6970
endif()
7071

72+
if(SOURCEMETA_CORE_LANG_NUMERIC)
73+
find_package(mpdecimal REQUIRED)
74+
add_subdirectory(src/lang/numeric)
75+
endif()
76+
7177
if(SOURCEMETA_CORE_TIME)
7278
add_subdirectory(src/core/time)
7379
endif()
@@ -173,6 +179,10 @@ if(SOURCEMETA_CORE_TESTS)
173179
add_subdirectory(test/parallel)
174180
endif()
175181

182+
if(SOURCEMETA_CORE_LANG_NUMERIC)
183+
add_subdirectory(test/numeric)
184+
endif()
185+
176186
if(SOURCEMETA_CORE_TIME)
177187
add_subdirectory(test/time)
178188
endif()

cmake/Findmpdecimal.cmake

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
if(NOT mpdecimal_FOUND)
2+
set(MPDECIMAL_DIR "${PROJECT_SOURCE_DIR}/vendor/mpdecimal")
3+
set(MPDECIMAL_SOURCE_DIR "${MPDECIMAL_DIR}/libmpdec")
4+
set(MPDECIMAL_BINARY_DIR "${PROJECT_BINARY_DIR}/mpdecimal")
5+
6+
file(MAKE_DIRECTORY "${MPDECIMAL_BINARY_DIR}/include")
7+
8+
if(MSVC)
9+
configure_file(
10+
"${MPDECIMAL_SOURCE_DIR}/mpdecimal64vc.h"
11+
"${MPDECIMAL_BINARY_DIR}/include/mpdecimal.h"
12+
COPYONLY)
13+
set(MPD_CONFIG_LIST CONFIG_64 MASM)
14+
else()
15+
set(MPD_HEADER_CONFIG "/* ABI: 64-bit */")
16+
17+
if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|amd64|AMD64")
18+
set(MPD_CONFIG_LIST CONFIG_64 ASM)
19+
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|arm64")
20+
set(MPD_CONFIG_LIST CONFIG_64 ANSI HAVE_UINT128_T)
21+
else()
22+
set(MPD_CONFIG_LIST CONFIG_64 ANSI)
23+
endif()
24+
25+
configure_file(
26+
"${MPDECIMAL_SOURCE_DIR}/mpdecimal.h.in"
27+
"${MPDECIMAL_BINARY_DIR}/include/mpdecimal.h"
28+
@ONLY)
29+
endif()
30+
31+
set(MPDECIMAL_PUBLIC_HEADER "${MPDECIMAL_BINARY_DIR}/include/mpdecimal.h")
32+
33+
set(MPDECIMAL_SOURCES
34+
"${MPDECIMAL_SOURCE_DIR}/basearith.c"
35+
"${MPDECIMAL_SOURCE_DIR}/constants.c"
36+
"${MPDECIMAL_SOURCE_DIR}/context.c"
37+
"${MPDECIMAL_SOURCE_DIR}/convolute.c"
38+
"${MPDECIMAL_SOURCE_DIR}/crt.c"
39+
"${MPDECIMAL_SOURCE_DIR}/difradix2.c"
40+
"${MPDECIMAL_SOURCE_DIR}/fnt.c"
41+
"${MPDECIMAL_SOURCE_DIR}/fourstep.c"
42+
"${MPDECIMAL_SOURCE_DIR}/io.c"
43+
"${MPDECIMAL_SOURCE_DIR}/mpalloc.c"
44+
"${MPDECIMAL_SOURCE_DIR}/mpdecimal.c"
45+
"${MPDECIMAL_SOURCE_DIR}/mpsignal.c"
46+
"${MPDECIMAL_SOURCE_DIR}/numbertheory.c"
47+
"${MPDECIMAL_SOURCE_DIR}/sixstep.c"
48+
"${MPDECIMAL_SOURCE_DIR}/transpose.c")
49+
50+
if(MSVC)
51+
list(APPEND MPDECIMAL_SOURCES "${MPDECIMAL_SOURCE_DIR}/vcdiv64.asm")
52+
endif()
53+
54+
add_library(mpdecimal ${MPDECIMAL_SOURCES})
55+
56+
target_include_directories(mpdecimal PRIVATE
57+
"${MPDECIMAL_SOURCE_DIR}")
58+
59+
target_include_directories(mpdecimal PUBLIC
60+
"$<BUILD_INTERFACE:${MPDECIMAL_BINARY_DIR}/include>"
61+
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>")
62+
63+
target_compile_definitions(mpdecimal PUBLIC MPD_CONFIG_64)
64+
foreach(config_item ${MPD_CONFIG_LIST})
65+
target_compile_definitions(mpdecimal PRIVATE ${config_item})
66+
endforeach()
67+
68+
target_compile_definitions(mpdecimal PRIVATE NDEBUG)
69+
70+
if(SOURCEMETA_OS_LINUX)
71+
target_compile_definitions(mpdecimal PRIVATE _GNU_SOURCE)
72+
endif()
73+
74+
if(UNIX AND NOT APPLE)
75+
target_link_libraries(mpdecimal PRIVATE m)
76+
endif()
77+
78+
if(SOURCEMETA_COMPILER_LLVM OR SOURCEMETA_COMPILER_GCC)
79+
target_compile_options(mpdecimal PRIVATE -Wall -Wextra -Wno-unknown-pragmas)
80+
if(BUILD_SHARED_LIBS)
81+
target_compile_options(mpdecimal PUBLIC -fvisibility=default)
82+
endif()
83+
endif()
84+
85+
if(MSVC)
86+
if(BUILD_SHARED_LIBS)
87+
target_compile_definitions(mpdecimal PRIVATE BUILD_LIBMPDEC)
88+
else()
89+
target_compile_options(mpdecimal PRIVATE /wd4273)
90+
target_compile_definitions(mpdecimal PUBLIC BUILD_LIBMPDEC)
91+
endif()
92+
endif()
93+
94+
add_library(mpdecimal::mpdecimal ALIAS mpdecimal)
95+
96+
set_target_properties(mpdecimal
97+
PROPERTIES
98+
OUTPUT_NAME mpdecimal
99+
PUBLIC_HEADER "${MPDECIMAL_PUBLIC_HEADER}"
100+
C_VISIBILITY_PRESET "default"
101+
C_VISIBILITY_INLINES_HIDDEN FALSE
102+
POSITION_INDEPENDENT_CODE ON
103+
EXPORT_NAME mpdecimal)
104+
105+
if(SOURCEMETA_CORE_INSTALL)
106+
include(GNUInstallDirs)
107+
install(TARGETS mpdecimal
108+
EXPORT mpdecimal
109+
PUBLIC_HEADER DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
110+
COMPONENT sourcemeta_core_dev
111+
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
112+
COMPONENT sourcemeta_core
113+
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
114+
COMPONENT sourcemeta_core
115+
NAMELINK_COMPONENT sourcemeta_core_dev
116+
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
117+
COMPONENT sourcemeta_core_dev)
118+
install(EXPORT mpdecimal
119+
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/mpdecimal"
120+
NAMESPACE mpdecimal::
121+
COMPONENT sourcemeta_core_dev)
122+
123+
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/mpdecimal-config.cmake
124+
"include(\"\${CMAKE_CURRENT_LIST_DIR}/mpdecimal.cmake\")\n"
125+
"check_required_components(\"mpdecimal\")\n")
126+
install(FILES
127+
"${CMAKE_CURRENT_BINARY_DIR}/mpdecimal-config.cmake"
128+
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/mpdecimal"
129+
COMPONENT sourcemeta_core_dev)
130+
endif()
131+
132+
set(mpdecimal_FOUND ON)
133+
endif()

config.cmake.in

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ if(NOT SOURCEMETA_CORE_COMPONENTS)
77
list(APPEND SOURCEMETA_CORE_COMPONENTS io)
88
list(APPEND SOURCEMETA_CORE_COMPONENTS process)
99
list(APPEND SOURCEMETA_CORE_COMPONENTS parallel)
10+
list(APPEND SOURCEMETA_CORE_COMPONENTS numeric)
1011
list(APPEND SOURCEMETA_CORE_COMPONENTS time)
1112
list(APPEND SOURCEMETA_CORE_COMPONENTS uuid)
1213
list(APPEND SOURCEMETA_CORE_COMPONENTS md5)
@@ -34,6 +35,9 @@ foreach(component ${SOURCEMETA_CORE_COMPONENTS})
3435
elseif(component STREQUAL "parallel")
3536
find_dependency(Threads)
3637
include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_parallel.cmake")
38+
elseif(component STREQUAL "numeric")
39+
find_dependency(mpdecimal CONFIG)
40+
include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_numeric.cmake")
3741
elseif(component STREQUAL "time")
3842
include("${CMAKE_CURRENT_LIST_DIR}/sourcemeta_core_time.cmake")
3943
elseif(component STREQUAL "uuid")

src/core/json/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ if(SOURCEMETA_CORE_INSTALL)
77
endif()
88

99
target_link_libraries(sourcemeta_core_json PRIVATE sourcemeta::core::io)
10+
target_link_libraries(sourcemeta_core_json PUBLIC sourcemeta::core::numeric)

src/lang/numeric/CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
sourcemeta_library(NAMESPACE sourcemeta PROJECT core NAME numeric
2+
PRIVATE_HEADERS error.h decimal.h SOURCES decimal.cc)
3+
4+
if(SOURCEMETA_CORE_INSTALL)
5+
sourcemeta_library_install(NAMESPACE sourcemeta PROJECT core NAME numeric)
6+
endif()
7+
8+
target_link_libraries(sourcemeta_core_numeric PRIVATE mpdecimal)

0 commit comments

Comments
 (0)