Skip to content

Commit

Permalink
Extract numeric helpers from src/runtime into src/numeric
Browse files Browse the repository at this point in the history
Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>
  • Loading branch information
jviotti committed Sep 27, 2024
1 parent 57bdae3 commit 8c95d9b
Show file tree
Hide file tree
Showing 23 changed files with 225 additions and 221 deletions.
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ if(JSONBINPACK_TESTS)
find_package(GoogleTest REQUIRED)
enable_testing()

if(JSONBINPACK_NUMERIC)
add_subdirectory(test/numeric)
endif()

if(JSONBINPACK_RUNTIME)
add_subdirectory(test/runtime)
endif()
Expand Down
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ configure: .always
$(CMAKE) -S . -B ./build \
-DCMAKE_BUILD_TYPE:STRING=$(PRESET) \
-DCMAKE_COMPILE_WARNING_AS_ERROR:BOOL=ON \
-DJSONBINPACK_NUMERIC:BOOL=ON \
-DJSONBINPACK_RUNTIME:BOOL=ON \
-DJSONBINPACK_COMPILER:BOOL=ON \
-DJSONBINPACK_TESTS:BOOL=ON \
Expand Down
3 changes: 2 additions & 1 deletion src/numeric/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
noa_library(NAMESPACE sourcemeta PROJECT jsonbinpack NAME numeric
FOLDER "JSON BinPack/Numeric")
FOLDER "JSON BinPack/Numeric"
PRIVATE_HEADERS integral.h real.h zigzag.h)

if(JSONBINPACK_INSTALL)
noa_library_install(NAMESPACE sourcemeta PROJECT jsonbinpack NAME numeric)
Expand Down
24 changes: 3 additions & 21 deletions src/numeric/include/sourcemeta/jsonbinpack/numeric.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
#ifndef SOURCEMETA_JSONBINPACK_NUMERIC_H_
#define SOURCEMETA_JSONBINPACK_NUMERIC_H_

#include <cstdint> // std::uint8_t, std::int64_t
#include <limits> // std::numeric_limits

/// @defgroup numeric Numeric
/// @brief A comprehensive numeric library for JSON BinPack
///
Expand All @@ -13,23 +10,8 @@
/// #include <sourcemeta/jsonbinpack/numeric.h>
/// ```

namespace sourcemeta::jsonbinpack {

/// @ingroup numeric
template <typename T> constexpr auto is_byte(const T value) noexcept -> bool {
return value <= std::numeric_limits<std::uint8_t>::max();
}

/// @ingroup numeric
constexpr auto count_multiples(const std::int64_t minimum,
const std::int64_t maximum,
const std::int64_t multiplier) -> std::uint64_t {
assert(minimum <= maximum);
assert(multiplier > 0);
return static_cast<std::uint64_t>((maximum / multiplier) -
((minimum - 1) / multiplier));
}

} // namespace sourcemeta::jsonbinpack
#include <sourcemeta/jsonbinpack/numeric_integral.h>
#include <sourcemeta/jsonbinpack/numeric_real.h>
#include <sourcemeta/jsonbinpack/numeric_zigzag.h>

#endif
Original file line number Diff line number Diff line change
@@ -1,27 +1,39 @@
#ifndef SOURCEMETA_JSONBINPACK_RUNTIME_NUMERIC_H_
#define SOURCEMETA_JSONBINPACK_RUNTIME_NUMERIC_H_
#ifndef SOURCEMETA_JSONBINPACK_NUMERIC_INTEGRAL_H_
#define SOURCEMETA_JSONBINPACK_NUMERIC_INTEGRAL_H_

#include <cassert> // assert
#include <cmath> // std::abs
#include <cstdint> // std::uint8_t, std::int64_t, std::uint64_t
#include <limits> // std::numeric_limits

// TODO: Move to src/numeric

namespace sourcemeta::jsonbinpack {

template <unsigned int T> constexpr auto uint_max = (2 << (T - 1)) - 1;

/// @ingroup numeric
template <typename T> constexpr auto is_byte(const T value) noexcept -> bool {
return value <= std::numeric_limits<std::uint8_t>::max();
}

/// @ingroup numeric
constexpr auto count_multiples(const std::int64_t minimum,
const std::int64_t maximum,
const std::int64_t multiplier) -> std::uint64_t {
assert(minimum <= maximum);
assert(multiplier > 0);
return static_cast<std::uint64_t>((maximum / multiplier) -
((minimum - 1) / multiplier));
}

/// @ingroup numeric
template <unsigned int T> constexpr auto uint_max = (2 << (T - 1)) - 1;

/// @ingroup numeric
template <typename T>
constexpr auto is_within(const T value, const std::int64_t lower,
const std::int64_t higher) noexcept -> bool {
return value >= lower && value <= higher;
}

/// @ingroup numeric
template <typename T>
constexpr auto is_within(const T value, const std::uint64_t lower,
const std::uint64_t higher) noexcept -> bool {
Expand All @@ -33,6 +45,7 @@ constexpr auto is_within(const T value, const std::uint64_t lower,
}
}

/// @ingroup numeric
constexpr auto abs(const std::int64_t value) noexcept -> std::uint64_t {
if (value < 0) {
return static_cast<std::uint64_t>(value * -1);
Expand All @@ -41,6 +54,7 @@ constexpr auto abs(const std::int64_t value) noexcept -> std::uint64_t {
}
}

/// @ingroup numeric
constexpr auto divide_ceil(const std::int64_t dividend,
const std::uint64_t divisor) noexcept
-> std::int64_t {
Expand Down Expand Up @@ -68,6 +82,7 @@ constexpr auto divide_ceil(const std::int64_t dividend,
}
}

/// @ingroup numeric
constexpr auto divide_floor(const std::int64_t dividend,
const std::uint64_t divisor) noexcept
-> std::int64_t {
Expand All @@ -88,6 +103,7 @@ constexpr auto divide_floor(const std::int64_t dividend,
}
}

/// @ingroup numeric
constexpr auto closest_smallest_exponent(const std::uint64_t value,
const std::uint8_t base,
const std::uint8_t exponent_start,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
#ifndef SOURCEMETA_JSONBINPACK_RUNTIME_ENCODER_REAL_H_
#define SOURCEMETA_JSONBINPACK_RUNTIME_ENCODER_REAL_H_
#ifndef SOURCEMETA_JSONBINPACK_NUMERIC_REAL_H_
#define SOURCEMETA_JSONBINPACK_NUMERIC_REAL_H_

#include <cassert> // assert
#include <cmath> // std::modf, std::floor, std::isfinite
#include <concepts> // std::floating_point, std::integral

// TODO: Move to src/numeric

namespace sourcemeta::jsonbinpack {

// IEEE764 floating-point encoding is not precise. Some real numbers
// cannot be represented directly and thus approximations must be
// used. Here, we abuse those imprecision characteristics for
// space-efficiency by performing rounding on a very, very low
// threshold.
/// @ingroup numeric
template <std::floating_point Real>
constexpr auto correct_ieee764(const Real value) -> Real {
assert(std::isfinite(value));
Expand All @@ -29,6 +28,7 @@ constexpr auto correct_ieee764(const Real value) -> Real {
}
}

/// @ingroup numeric
template <std::integral Integer, std::floating_point Real>
constexpr auto real_digits(Real value, std::uint64_t *point_position)
-> Integer {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
#ifndef SOURCEMETA_JSONBINPACK_RUNTIME_ZIGZAG_H_
#define SOURCEMETA_JSONBINPACK_RUNTIME_ZIGZAG_H_
#ifndef SOURCEMETA_JSONBINPACK_NUMERIC_ZIGZAG_H_
#define SOURCEMETA_JSONBINPACK_NUMERIC_ZIGZAG_H_

#include <cmath> // std::abs
#include <cstdint> // std::uint64_t, std::int64_t

// TODO: Move to src/numeric

namespace sourcemeta::jsonbinpack {

/// @ingroup numeric
constexpr auto zigzag_encode(const std::int64_t value) noexcept
-> std::uint64_t {
if (value >= 0) {
Expand All @@ -17,6 +16,7 @@ constexpr auto zigzag_encode(const std::int64_t value) noexcept
return (static_cast<std::uint64_t>(std::abs(value)) * 2) - 1;
}

/// @ingroup numeric
constexpr auto zigzag_decode(const std::uint64_t value) noexcept
-> std::int64_t {
if (value % 2 == 0) {
Expand Down
6 changes: 4 additions & 2 deletions src/runtime/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ noa_library(NAMESPACE sourcemeta PROJECT jsonbinpack NAME runtime
FOLDER "JSON BinPack/Runtime"
PRIVATE_HEADERS
decoder.h decoder_basic.h
encoder.h encoder_basic.h encoder_context.h encoder_real.h
encoder.h encoder_basic.h encoder_context.h
plan.h plan_wrap.h parser.h
zigzag.h varint.h numeric.h
varint.h
SOURCES runtime_parser.cc runtime_parser_v1.h)

if(JSONBINPACK_INSTALL)
Expand All @@ -13,3 +13,5 @@ endif()

target_link_libraries(sourcemeta_jsonbinpack_runtime PUBLIC
sourcemeta::jsontoolkit::json)
target_link_libraries(sourcemeta_jsonbinpack_runtime PUBLIC
sourcemeta::jsonbinpack::numeric)
3 changes: 2 additions & 1 deletion src/runtime/include/sourcemeta/jsonbinpack/runtime_decoder.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#ifndef SOURCEMETA_JSONBINPACK_RUNTIME_DECODER_H_
#define SOURCEMETA_JSONBINPACK_RUNTIME_DECODER_H_

#include <sourcemeta/jsonbinpack/numeric.h>

#include <sourcemeta/jsonbinpack/runtime_decoder_basic.h>
#include <sourcemeta/jsonbinpack/runtime_numeric.h>
#include <sourcemeta/jsonbinpack/runtime_plan.h>
#include <sourcemeta/jsonbinpack/runtime_plan_wrap.h>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
#define SOURCEMETA_JSONBINPACK_RUNTIME_DECODER_BASIC_H_
#ifndef DOXYGEN

#include <sourcemeta/jsonbinpack/numeric.h>

#include <sourcemeta/jsonbinpack/runtime_varint.h>
#include <sourcemeta/jsonbinpack/runtime_zigzag.h>

#include <cassert> // assert
#include <cmath> // std::ceil
Expand Down
4 changes: 2 additions & 2 deletions src/runtime/include/sourcemeta/jsonbinpack/runtime_encoder.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#ifndef SOURCEMETA_JSONBINPACK_RUNTIME_ENCODER_H_
#define SOURCEMETA_JSONBINPACK_RUNTIME_ENCODER_H_

#include <sourcemeta/jsonbinpack/numeric.h>

#include <sourcemeta/jsonbinpack/runtime_encoder_basic.h>
#include <sourcemeta/jsonbinpack/runtime_encoder_real.h>
#include <sourcemeta/jsonbinpack/runtime_numeric.h>
#include <sourcemeta/jsonbinpack/runtime_plan.h>
#include <sourcemeta/jsonbinpack/runtime_plan_wrap.h>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
#define SOURCEMETA_JSONBINPACK_RUNTIME_ENCODER_BASIC_H_
#ifndef DOXYGEN

#include <sourcemeta/jsonbinpack/numeric.h>

#include <sourcemeta/jsonbinpack/runtime_encoder_context.h>
#include <sourcemeta/jsonbinpack/runtime_varint.h>
#include <sourcemeta/jsonbinpack/runtime_zigzag.h>

#include <algorithm> // std::find_if
#include <cassert> // assert
Expand Down
3 changes: 2 additions & 1 deletion src/runtime/include/sourcemeta/jsonbinpack/runtime_plan.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#ifndef SOURCEMETA_JSONBINPACK_RUNTIME_ENCODING_H_
#define SOURCEMETA_JSONBINPACK_RUNTIME_ENCODING_H_

#include <sourcemeta/jsonbinpack/runtime_numeric.h>
#include <sourcemeta/jsonbinpack/numeric.h>

#include <sourcemeta/jsontoolkit/json.h>

#include <cstdint> // std::int64_t, std::uint64_t
Expand Down
17 changes: 17 additions & 0 deletions test/numeric/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
add_executable(sourcemeta_jsonbinpack_numeric_unit
zigzag_test.cc
closest_smallest_exponent_test.cc
divide_ceil_test.cc
divide_floor_test.cc
uint_max_test.cc)

noa_add_default_options(PRIVATE sourcemeta_jsonbinpack_numeric_unit)

target_link_libraries(sourcemeta_jsonbinpack_numeric_unit
PRIVATE GTest::gtest GTest::gtest_main)
target_link_libraries(sourcemeta_jsonbinpack_numeric_unit
PRIVATE sourcemeta::jsonbinpack::numeric)

gtest_discover_tests(sourcemeta_jsonbinpack_numeric_unit)
set_target_properties(sourcemeta_jsonbinpack_numeric_unit
PROPERTIES FOLDER "JSON BinPack/Numeric")
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include <gtest/gtest.h>

#include <sourcemeta/jsonbinpack/runtime.h>
#include <sourcemeta/jsonbinpack/numeric.h>

TEST(JSONBinPack_numeric, closest_smallest_exponent_2_2_1_2) {
EXPECT_EQ(sourcemeta::jsonbinpack::closest_smallest_exponent(2, 2, 1, 2), 1);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
#include <gtest/gtest.h>

#include <cstdint>
#include <limits>

#include <sourcemeta/jsonbinpack/runtime.h>
#include <sourcemeta/jsonbinpack/numeric.h>

TEST(JSONBinPack_numeric, divide_ceil_simple_positive) {
const std::int64_t dividend{10};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
#include <gtest/gtest.h>

#include <cstdint>
#include <limits>

#include <sourcemeta/jsonbinpack/runtime.h>
#include <sourcemeta/jsonbinpack/numeric.h>

TEST(JSONBinPack_numeric, divide_floor_simple_positive) {
const std::int64_t dividend{10};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
#include <gtest/gtest.h>

#include <cstdint> // std::uint8_t
#include <limits> // std::numeric_limits

#include <sourcemeta/jsonbinpack/runtime.h>
#include <sourcemeta/jsonbinpack/numeric.h>

TEST(JSONBinPack_numeric, uint_max_8) {
EXPECT_EQ(sourcemeta::jsonbinpack::uint_max<8>,
Expand Down
Loading

0 comments on commit 8c95d9b

Please sign in to comment.