Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
7b622a7
feature: coding of aggregate
xDimon Jan 24, 2025
2b2969e
refactor: use concepts
xDimon Jan 25, 2025
397f5db
fix: incomplete concepts
xDimon Jan 27, 2025
6baec5c
fix: SomeSpan concept
xDimon Jan 28, 2025
9a01004
update: version of used hunter
xDimon Jan 28, 2025
c4c2383
fix: CI
xDimon Jan 28, 2025
fdc1663
fix: CI
xDimon Jan 28, 2025
b81ba08
fix: CI
xDimon Jan 28, 2025
f325334
update: hunter and qtils
xDimon Jan 28, 2025
eb74ac4
refactor: used macros
xDimon Jan 28, 2025
3bb4394
fix: try to fix CI (update macos)
xDimon Jan 28, 2025
c997a5c
update: qtils
xDimon Jan 28, 2025
a401adc
refactor: rename as_decomposed
xDimon Jan 30, 2025
0a74ea0
feature: generate aggregate.hpp in according MAX_AGGREGATE_FIELDS cma…
xDimon Jan 30, 2025
7eaee7f
update: qtils
xDimon Jan 30, 2025
c5349eb
update: qtils
xDimon Jan 30, 2025
8a0e43c
fix: redundant decay_t using
xDimon Jan 30, 2025
965bf3f
feature: custom discomposing
xDimon Jan 30, 2025
9ea5b57
fix: review issues
xDimon Jan 30, 2025
4d35097
don't overwrite aggregate.hpp
turuslan Jan 30, 2025
5769acc
fix constructible on macos
turuslan Jan 30, 2025
f89839d
Revert "don't overwrite aggregate.hpp"
turuslan Jan 30, 2025
88988d4
don't overwrite aggregate.hpp
turuslan Jan 30, 2025
1461bb4
fix makefile
turuslan Jan 30, 2025
fb0a319
update: qtils
xDimon Jan 30, 2025
6bdc80b
configure_file definitions
turuslan Jan 30, 2025
08122a3
update: qtils
xDimon Feb 3, 2025
7a418d9
update: qtils hunter config
xDimon Feb 3, 2025
04bea1a
update: qtils
xDimon Feb 3, 2025
2dde730
update: qtils
xDimon Feb 3, 2025
6dbe202
update: qtils
xDimon Feb 3, 2025
e31f904
refactor: complete support fixed-width and compact integers
xDimon Feb 5, 2025
c30e4a7
feature: CompactReflection for coding int value as compact
xDimon Feb 5, 2025
9576c5d
fix: review issues
xDimon Feb 6, 2025
312aaae
update: qtils
xDimon Feb 6, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ cmake_minimum_required(VERSION 3.12)

option(JAM_COMPATIBLE "Build compatible with JAM-codec" OFF)
option(CUSTOM_CONFIG_SUPPORT "Support custom config of streams" OFF)
set(MAX_AGGREGATE_FIELDS 20 CACHE STRING "Max number of aggregates fields (1..1000); for generation")

option(BUILD_TESTS "Whether to include the test suite in build" OFF)

Expand Down
5 changes: 5 additions & 0 deletions include/scale/detail/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Ignored because part of this file is generated by CMake.
# If changes to the base content need to be committed, they must be committed explicitly,
# except for the section between `-BEGIN-GENERATED-SECTION-` and `-END-GENERATED-SECTION-`,
# which is automatically generated and should not be committed.
aggregate.hpp
67 changes: 4 additions & 63 deletions include/scale/detail/aggregate.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,73 +9,14 @@

namespace scale::detail {

template <typename T, typename F>
requires SimpleCodeableAggregate<T>
auto &as_decomposed(T &&v, const F &f) {
template <SimpleCodeableAggregate T, typename F>
decltype(auto) decompose_and_apply(T &&v, const F &f) {
constexpr auto N = field_number_of<T>;
// clang-format off
if constexpr (N == 0) {
return f();
} else if constexpr (N == 1) {
auto &[v1] = v;
return f(v1);
} else if constexpr (N == 2) {
auto &[v1, v2] = v;
return f(v1, v2);
} else if constexpr (N == 3) {
auto &[v1, v2, v3] = v;
return f(v1, v2, v3);
} else if constexpr (N == 4) {
auto &[v1, v2, v3, v4] = v;
return f(v1, v2, v3, v4);
} else if constexpr (N == 5) {
auto &[v1, v2, v3, v4, v5] = v;
return f(v1, v2, v3, v4, v5);
} else if constexpr (N == 6) {
auto &[v1, v2, v3, v4, v5, v6] = v;
return f(v1, v2, v3, v4, v5, v6);
} else if constexpr (N == 7) {
auto &[v1, v2, v3, v4, v5, v6, v7] = v;
return f(v1, v2, v3, v4, v5, v6, v7);
} else if constexpr (N == 8) {
auto &[v1, v2, v3, v4, v5, v6, v7, v8] = v;
return f(v1, v2, v3, v4, v5, v6, v7, v8);
} else if constexpr (N == 9) {
auto &[v1, v2, v3, v4, v5, v6, v7, v8, v9] = v;
return f(v1, v2, v3, v4, v5, v6, v7, v8, v9);
} else if constexpr (N == 10) {
auto &[v1, v2, v3, v4, v5, v6, v7, v8, v9, v10] = v;
return f(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10);
} else if constexpr (N == 11) {
auto &[v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11] = v;
return f(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11);
} else if constexpr (N == 12) {
auto &[v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12] = v;
return f(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12);
} else if constexpr (N == 13) {
auto &[v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13] = v;
return f(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13);
} else if constexpr (N == 14) {
auto &[v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14] = v;
return f(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14);
} else if constexpr (N == 15) {
auto &[v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15] = v;
return f(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15);
} else if constexpr (N == 16) {
auto &[v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16] = v;
return f(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16);
} else if constexpr (N == 17) {
auto &[v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17] = v;
return f(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17);
} else if constexpr (N == 18) {
auto &[v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18] = v;
return f(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18);
} else if constexpr (N == 19) {
auto &[v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19] = v;
return f(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19);
} else if constexpr (N == 20) {
auto &[v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20] = v;
return f(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20);
// -BEGIN-GENERATED-SECTION-
// -END-GENERATED-SECTION-
} else {
// We mustn't fall in here
static_assert(N <= MAX_FIELD_NUM, "Inconsistent value of MAX_FIELD_NUM");
Expand Down
8 changes: 4 additions & 4 deletions include/scale/scale_decoder_stream.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,10 @@ namespace scale {
* @return reference to stream
*/
ScaleDecoderStream &operator>>(SimpleCodeableAggregate auto &v) {
return detail::as_decomposed(v,
[&](auto &...args) -> ScaleDecoderStream & {
return (*this >> ... >> args);
});
return detail::decompose_and_apply(
v, [&](auto &...args) -> ScaleDecoderStream & {
return (*this >> ... >> args);
});
}

/**
Expand Down
2 changes: 1 addition & 1 deletion include/scale/scale_encoder_stream.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ namespace scale {
* @return reference to stream
*/
ScaleEncoderStream &operator<<(const SimpleCodeableAggregate auto &v) {
return detail::as_decomposed(
return detail::decompose_and_apply(
v, [&](const auto &...args) -> ScaleEncoderStream & {
return (*this << ... << args);
});
Expand Down
96 changes: 96 additions & 0 deletions scripts/generate_aggregate_hpp.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
#!/bin/sh

# This script modifies a specified C++ source file by replacing a generated section.
# It reads the file, finds the markers '-BEGIN-GENERATED-SECTION-' and '-END-GENERATED-SECTION-',
# generates C++ code based on a given integer N, and writes the modified content back to the file.
# If the markers are not found, the script exits with an error without modifying the file.
# If the file is modified, the specified stamp file is updated (if provided).
# Usage: ./generate_aggregate_hpp.sh <filename> <N> [stampfile]
# Where <filename> is the path to the C++ source file, <N> is an integer between 0 and 1000,
# and [stampfile] is an optional path to the stamp file to be updated.

# Validate input
if [ "$#" -lt 2 ] || [ "$#" -gt 3 ]; then
echo "Usage: $0 <filename> <N> [stampfile]"
exit 1
fi

FILENAME="$1"
N="$2"
STAMPFILE="$3"

if [ ! -f "$FILENAME" ]; then
echo "Error: File '$FILENAME' not found."
exit 1
fi

if echo "$N" | grep -q "[^0-9]" || [ "$N" -lt 0 ] || [ "$N" -gt 1000 ]; then
echo "N must be an integer between 0 and 1000"
exit 1
fi

# Find the section markers
BEGIN_LINE=$(awk '/-BEGIN-GENERATED-SECTION-/ {print NR; exit}' "$FILENAME")
END_LINE=$(awk '/-END-GENERATED-SECTION-/ {print NR; exit}' "$FILENAME")

if [ -z "$BEGIN_LINE" ] || [ -z "$END_LINE" ]; then
echo "Error: Required markers not found in the file."
exit 1
fi

# Create temporary file
tempfile=$(mktemp) || { echo "Failed to create temporary file"; exit 1; }

# Trap to ensure the temporary file is deleted in case of errors
trap 'rm -f "$tempfile"' EXIT

# Write the modified content to the temporary file
awk -v begin="$BEGIN_LINE" -v end="$END_LINE" -v n="$N" '
BEGIN { in_generated_section = 0; }
{
if (NR == begin) {
print; # Print the BEGIN marker
in_generated_section = 1;
for (i = 1; i <= n; i++) {
printf " } else if constexpr (N == %d) {\n", i;
printf " auto &[";
for (j = 1; j <= i; j++) {
printf "v%d%s", j, (j < i ? ", " : "");
}
printf "] = v;\n";
printf " return f(";
for (j = 1; j <= i; j++) {
printf "v%d%s", j, (j < i ? ", " : "");
}
printf ");\n";
}
next;
}
if (NR == end) {
print; # Print the END marker
in_generated_section = 0;
next;
}
if (!in_generated_section) {
print;
}
}' "$FILENAME" > "$tempfile" || { echo "Error processing file"; exit 1; }

# Check if the file has changed before overwriting
if ! cmp -s "$tempfile" "$FILENAME"; then
mv "$tempfile" "$FILENAME"
if [ -n "$STAMPFILE" ]; then
touch "$STAMPFILE"
echo "File '$FILENAME' successfully updated. Stamp file '$STAMPFILE' modified."
else
echo "File '$FILENAME' successfully updated."
fi
else
rm -f "$tempfile"
echo "No changes detected."
fi

# Remove trap on success
trap - EXIT

exit 0
13 changes: 13 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
set(SCRIPT_PATH "${CMAKE_SOURCE_DIR}/scripts/generate_aggregate_hpp.sh")
set(TARGET_FILE "${CMAKE_SOURCE_DIR}/include/scale/detail/aggregate.hpp")
set(STAMP_FILE "${CMAKE_BINARY_DIR}/include/scale/detail/aggregate.hpp.stamp")
add_custom_command(
OUTPUT ${STAMP_FILE}
COMMAND ${CMAKE_COMMAND} -E echo "Running: ${SCRIPT_PATH} '${TARGET_FILE}' '${MAX_AGGREGATE_FIELDS}' '${STAMP_FILE}'"
COMMAND ${SCRIPT_PATH} ${TARGET_FILE} ${MAX_AGGREGATE_FIELDS} ${STAMP_FILE}
DEPENDS ${SCRIPT_PATH} ${TARGET_FILE}
COMMENT "Generating include/scale/detail/aggregate.hpp"
VERBATIM
)
add_custom_target(generate_aggregate_hpp ALL DEPENDS ${STAMP_FILE})

add_library(scale
encode_append.cpp
scale_decoder_stream.cpp
Expand Down
Loading