Compare commits

..

72 Commits

Author SHA1 Message Date
JCW
416251b2bc Update conan lock 2026-04-23 13:50:52 +01:00
JCW
55fba082e0 Add spdlog to xrpld 2026-04-23 12:29:18 +01:00
Alex Kremer
b41cbb08c6 chore: Add pre-commit hook to fix include style (#6995)
Co-authored-by: Ayaz Salikhov <mathbunnyru@users.noreply.github.com>
2026-04-22 22:20:14 +00:00
pdp2121
bd1b126230 feat: Add --definitions flag and artifact (#6858)
Co-authored-by: Ayaz Salikhov <mathbunnyru@users.noreply.github.com>
2026-04-22 20:10:52 +00:00
Mayukha Vadari
1c6cdc653c fix: More clang-tidy issues (#6992) 2026-04-22 17:42:15 +00:00
Alex Kremer
4ab20770f7 chore: Optionally run clang-tidy via pre-commit (#6680)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Ayaz Salikhov <mathbunnyru@users.noreply.github.com>
Co-authored-by: Bart <bthomee@users.noreply.github.com>
2026-04-22 15:06:36 +00:00
Vito Tumas
2e307329f0 refactor: Add transaction-specific invariant checking (#6551) 2026-04-22 14:41:19 +00:00
Ayaz Salikhov
3429845c40 style: Add bashate pre-commit hook to unify bash style (#6994) 2026-04-22 14:26:02 +00:00
Alex Kremer
7c7c1894b9 chore: Add -fix to clang-tidy invocation (#6990) 2026-04-21 19:00:00 +00:00
Jingchen
45d4aacb53 chore: Remove empty Taker.h (#6984) 2026-04-21 18:15:58 +00:00
Alex Kremer
ce3951bbb3 chore: Enable clang-tidy modernize checks (#6975)
Co-authored-by: Bart <11445373+bthomee@users.noreply.github.com>
Co-authored-by: Bart <bthomee@users.noreply.github.com>
2026-04-21 15:32:51 +00:00
Ayaz Salikhov
ab887f5049 ci: Upload clang-tidy git diff (#6983) 2026-04-21 14:22:33 +00:00
Alex Kremer
ea023121f5 fix: Add rounding to Vault invariants (#6217) (#6955)
Co-authored-by: Vito Tumas <5780819+Tapanito@users.noreply.github.com>
Co-authored-by: Ed Hennis <ed@ripple.com>
2026-04-21 12:14:07 +00:00
yinyiqian1
4b198cd5bb fix: Disallow MPTClearRequireAuth if is set (#6712)
Co-authored-by: Ayaz Salikhov <mathbunnyru@users.noreply.github.com>
2026-04-20 21:25:52 +00:00
Alex Kremer
726f20c8f6 feat: Add GRPC TLS support (#6374)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-20 17:12:14 +00:00
Zhiyuan Wang
96643bb0fa fix: Check for empty sfAdditionalBooks array in hybrid offer invariant (#6716) 2026-04-20 17:10:28 +00:00
chuanshanjida
e83818241a chore: Remove repetitive word in multiple files (#6978)
Signed-off-by: chuanshanjida <chuanshanjida@outlook.com>
2026-04-20 16:56:03 +00:00
Ayaz Salikhov
852fbe955d ci: Add workflow to check PR description has been filled (#6965) 2026-04-20 12:12:58 +00:00
dependabot[bot]
b33d0a0479 ci: [DEPENDABOT] Bump tj-actions/changed-files from 47.0.5 to 47.0.6 (#6973)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-20 11:20:42 +00:00
Alex Kremer
653a383ff5 chore: Enable clang-tidy include cleaner (#6947) 2026-04-17 16:43:49 +00:00
Gregory Tsipenyuk
affe5835fe fix: Change AMMClawback return code to tecNO_PERMISSION (#6946) 2026-04-17 14:19:58 +00:00
dependabot[bot]
ef2642f873 ci: [DEPENDABOT] bump actions/upload-pages-artifact from 4.0.0 to 5.0.0 (#6927)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-17 14:02:02 +00:00
dependabot[bot]
b2038163bc ci: [DEPENDABOT] bump actions/upload-artifact from 7.0.0 to 7.0.1 (#6928)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-17 14:01:56 +00:00
Alex Kremer
f1a5ba43ad chore: Enable clang-tidy readability checks (#6930)
Co-authored-by: Ayaz Salikhov <mathbunnyru@users.noreply.github.com>
2026-04-17 13:30:52 +00:00
Jingchen
4a73be499d fix: Fix unity build for book step (#6942)
Co-authored-by: xrplf-ai-reviewer[bot] <266832837+xrplf-ai-reviewer[bot]@users.noreply.github.com>
2026-04-16 17:12:00 +00:00
Sergey Kuznetsov
d52d735543 chore: Move codegen venv setup into build stage (#6617)
Co-authored-by: JCW <a1q123456@users.noreply.github.com>
Co-authored-by: Bart <bthomee@users.noreply.github.com>
2026-04-15 18:50:49 +00:00
Alex Kremer
6a0ce46755 chore: Enable most clang-tidy bugprone checks (#6929)
Co-authored-by: Ayaz Salikhov <mathbunnyru@users.noreply.github.com>
2026-04-14 20:24:21 +00:00
Bart
2f029a2120 refactor: Improve exception handling (#6540) (#6735)
Co-authored-by: Bart <11445373+bthomee@users.noreply.github.com>
2026-04-14 17:14:24 +00:00
Zhiyuan Wang
61fbde3a71 refactor: Remove unused notTooManyOffers function from NFTokenUtils (#6737) 2026-04-13 23:18:10 +00:00
Bart
e2e537b3bb fix: Change Tuning::bookOffers minimum limit to 1 (#6812)
Co-authored-by: Bart <11445373+bthomee@users.noreply.github.com>
2026-04-10 14:38:46 +00:00
Ed Hennis
a873250019 chore: Make pre-commit line ending conversions work on Windows (#6832) (#6833) 2026-04-10 10:12:52 +00:00
Gregory Tsipenyuk
56c9d1d497 fix: Add description for terLOCKED error (#6811) 2026-04-08 20:56:19 +00:00
yinyiqian1
d52dd29d20 fix: Address AI reviewer comments for Permission Delegation (#6675) 2026-04-08 20:22:19 +00:00
Mayukha Vadari
7793b5f10b refactor: Combine AMMHelpers and AMMUtils (#6733) 2026-04-08 17:38:33 +00:00
Gregory Tsipenyuk
dfcad69155 feat: Add MPT support to DEX (#5285) 2026-04-08 16:17:37 +00:00
Pratik Mankawde
6d1a5be8d2 fix: Handle WSClient write failure when server closes WebSocket (#6671)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 19:15:40 +00:00
Ayaz Salikhov
b0fe2ec58a ci: Change conditions for uploading artifacts in public/private/org repos (#6734) 2026-04-07 14:32:13 +00:00
Bart
c00ed673a8 refactor: Rename non-functional uses of ripple(d) to xrpl(d) (#6676)
Co-authored-by: Bart <11445373+bthomee@users.noreply.github.com>
2026-04-07 13:00:17 +00:00
Mayukha Vadari
f239256d87 refactor: Move more helper files into libxrpl/ledger/helpers (#6731)
Co-authored-by: xrplf-ai-reviewer[bot] <266832837+xrplf-ai-reviewer[bot]@users.noreply.github.com>
2026-04-06 22:36:32 +00:00
Mayukha Vadari
00761dbb67 fix: Minor RPC fixes (#6730) 2026-04-06 22:15:16 +00:00
Zhiyuan Wang
077e03ff33 fix: Prevent deletion of MPTokens with active escrow (#6635)
Co-authored-by: Bart <bthomee@users.noreply.github.com>
2026-04-06 17:51:46 +00:00
Vito Tumas
7d524a03b8 fix: Clamp VaultClawback to assetsAvailable for zero-amount clawback (#6646) 2026-04-06 15:13:03 +00:00
Vito Tumas
c0ee813666 fix: Add assorted Lending Protocol fixes (#6678)
Co-authored-by: Shawn Xie <35279399+shawnxie999@users.noreply.github.com>
2026-04-03 17:41:45 +00:00
Mayukha Vadari
8e05416211 fix: Change variable signedness and correctly handle std::optional (#6657) 2026-04-03 15:16:50 +00:00
Mayukha Vadari
81555d5456 refactor: Reorganize RPC handler files (#6628) 2026-04-02 23:46:17 +00:00
Ayaz Salikhov
6b55c4cdc8 chore: Update XRPLF/actions (#6713) 2026-04-02 21:34:20 +00:00
yinyiqian1
3414a1776b docs: Add explanatory comment to checkFee (#6631) 2026-04-02 20:48:35 +00:00
yinyiqian1
6d9ed125f3 fix: Decouple reserve from fee in delegate payment (#6568) 2026-04-02 20:48:00 +00:00
Vito Tumas
02fa55df8d fix: Check trustline limits for share-denominated vault withdrawals (#6645) 2026-04-01 19:31:45 +00:00
Valentin Balaschenko
6e2452207d fix: Remove fatal assertion on Linux thread name truncation (#6690) 2026-04-01 16:56:45 +00:00
Alex Kremer
29e49abd3c chore: Enable clang-tidy coreguidelines checks (#6698)
Co-authored-by: Ayaz Salikhov <mathbunnyru@users.noreply.github.com>
2026-04-01 15:46:14 +00:00
Ayaz Salikhov
ae21f53e4d ci: Allow uploading artifacts for XRPLF org (#6702) 2026-04-01 13:37:35 +00:00
Vito Tumas
bee1056faa fix: Enforce aggregate MaximumAmount in multi-send MPT (#6644)
Co-authored-by: xrplf-ai-reviewer[bot] <266832837+xrplf-ai-reviewer[bot]@users.noreply.github.com>
2026-04-01 13:35:13 +00:00
Ayaz Salikhov
b6aa4a8fde chore: Use nudb recipe from the upstream (#6701) 2026-04-01 10:33:02 +00:00
Mayukha Vadari
a9afd2c116 fix: Fix previous ledger size typo in RCLConsensus (#6696) 2026-03-31 19:56:30 +00:00
Alex Kremer
2502befb42 chore: Enable clang-tidy misc checks (#6655) 2026-03-31 17:29:45 +00:00
Ayaz Salikhov
c3fae847f3 ci: Use pull_request_target to check for signed commits (#6697) 2026-03-31 17:14:41 +00:00
Bart
7f53351920 chore: Remove unnecessary clang-format off/on directives (#6682)
Co-authored-by: Bart <11445373+bthomee@users.noreply.github.com>
2026-03-31 15:38:04 +00:00
Pratik Mankawde
bb95a7d6cd fix: Fix Workers::stop() race between m_allPaused and m_runningTaskCount (#6574)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 15:06:04 +00:00
Ayaz Salikhov
5c8dfe5456 ci: Only publish docs in public repos (#6687) 2026-03-30 17:15:40 +00:00
Alex Kremer
ab8c168e3b chore: Enable remaining clang-tidy performance checks (#6648)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-30 17:08:47 +00:00
Jingchen
3a477e4d01 refactor: Address PR comments after the modularisation PRs (#6389)
Signed-off-by: JCW <a1q123456@users.noreply.github.com>
Co-authored-by: Bart <bthomee@users.noreply.github.com>
2026-03-30 15:22:38 +00:00
Alex Kremer
96bfc32fe2 chore: Fix clang-tidy header filter (#6686) 2026-03-30 14:59:53 +00:00
dependabot[bot]
de671863e2 ci: [DEPENDABOT] bump actions/deploy-pages from 4.0.5 to 5.0.0 (#6684)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-30 14:09:57 +00:00
dependabot[bot]
e0cabb9f8c ci: [DEPENDABOT] bump codecov/codecov-action from 5.5.3 to 6.0.0 (#6685)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-30 13:57:32 +00:00
Pratik Mankawde
3d9c545f59 fix: Guard Coro::resume() against completed coroutines (#6608)
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-27 18:52:18 +00:00
Vito Tumas
9b944ee8c2 refactor: Split LoanInvariant into LoanBrokerInvariant and LoanInvariant (#6674) 2026-03-27 18:35:42 +00:00
Ayaz Salikhov
509677abfd ci: Don't publish docs on release branches (#6673) 2026-03-26 14:11:37 +00:00
Jingchen
addc1e8e25 refactor: Make function naming in ServiceRegistry consistent (#6390)
Signed-off-by: JCW <a1q123456@users.noreply.github.com>
Co-authored-by: Ed Hennis <ed@ripple.com>
2026-03-26 14:11:16 +00:00
Valentin Balaschenko
faf69da4b0 chore: Shorten job names to stay within Linux 15-char thread limit (#6669) 2026-03-26 14:10:51 +00:00
Vito Tumas
76e3b4fb0f fix: Improve loan invariant message (#6668) 2026-03-26 12:40:26 +00:00
Ayaz Salikhov
e8bdbf975a ci: Upload artifacts only in public repositories (#6670) 2026-03-26 12:37:37 +00:00
1562 changed files with 61930 additions and 64764 deletions

View File

@@ -1,10 +1,11 @@
---
# This entire group of checks was applied to all cpp files but not all header files.
# ---
Checks: "-*,
bugprone-argument-comment,
bugprone-assert-side-effect,
bugprone-bad-signal-to-kill-thread,
bugprone-bool-pointer-implicit-conversion,
bugprone-capturing-this-in-member-variable,
bugprone-casting-through-void,
bugprone-chained-comparison,
bugprone-compare-pointer-to-member-virtual-function,
@@ -24,7 +25,6 @@ Checks: "-*,
bugprone-lambda-function-name,
bugprone-macro-parentheses,
bugprone-macro-repeated-side-effects,
bugprone-misleading-setter-of-reference,
bugprone-misplaced-operator-in-strlen-in-alloc,
bugprone-misplaced-pointer-arithmetic-in-alloc,
bugprone-misplaced-widening-cast,
@@ -66,17 +66,17 @@ Checks: "-*,
bugprone-terminating-continue,
bugprone-throw-keyword-missing,
bugprone-too-small-loop-variable,
bugprone-unchecked-optional-access,
# bugprone-unchecked-optional-access, # see https://github.com/XRPLF/rippled/pull/6502
bugprone-undefined-memory-manipulation,
bugprone-undelegated-constructor,
bugprone-unhandled-exception-at-new,
bugprone-unhandled-self-assignment,
bugprone-unique-ptr-array-mismatch,
bugprone-unsafe-functions,
bugprone-unused-local-non-trivial-variable,
bugprone-use-after-move, # has issues
bugprone-unused-raii,
bugprone-unused-return-value,
bugprone-use-after-move,
bugprone-unused-local-non-trivial-variable,
bugprone-virtual-near-miss,
cppcoreguidelines-init-variables,
cppcoreguidelines-misleading-capture-default-by-value,
@@ -85,10 +85,8 @@ Checks: "-*,
cppcoreguidelines-pro-type-static-cast-downcast,
cppcoreguidelines-rvalue-reference-param-not-moved,
cppcoreguidelines-use-default-member-init,
cppcoreguidelines-use-enum-class,
cppcoreguidelines-virtual-class-destructor,
hicpp-ignored-remove-result,
llvm-namespace-comment,
misc-const-correctness,
misc-definitions-in-headers,
misc-header-include-cycle,
@@ -100,7 +98,6 @@ Checks: "-*,
misc-unused-alias-decls,
misc-unused-using-decls,
modernize-concat-nested-namespaces,
modernize-deprecated-headers,
modernize-make-shared,
modernize-make-unique,
modernize-pass-by-value,
@@ -109,13 +106,13 @@ Checks: "-*,
modernize-use-emplace,
modernize-use-equals-default,
modernize-use-equals-delete,
modernize-use-nodiscard,
modernize-use-override,
modernize-use-ranges,
modernize-use-scoped-lock,
modernize-use-starts-ends-with,
modernize-use-std-numbers,
modernize-use-using,
modernize-deprecated-headers,
llvm-namespace-comment,
performance-faster-string-find,
performance-for-range-copy,
performance-implicit-conversion-in-loop,
@@ -124,7 +121,6 @@ Checks: "-*,
performance-move-constructor-init,
performance-no-automatic-move,
performance-trivially-destructible,
readability-ambiguous-smartptr-reset-call,
readability-avoid-nested-conditional-operator,
readability-avoid-return-with-void-value,
readability-braces-around-statements,
@@ -135,7 +131,6 @@ Checks: "-*,
readability-duplicate-include,
readability-else-after-return,
readability-enum-initial-value,
readability-identifier-naming,
readability-implicit-bool-conversion,
readability-make-member-function-const,
readability-math-missing-parentheses,
@@ -153,47 +148,52 @@ Checks: "-*,
readability-use-std-min-max
"
# ---
# other checks that have issues that need to be resolved:
#
# readability-inconsistent-declaration-parameter-name, # in this codebase this check will break a lot of arg names
# readability-static-accessed-through-instance, # this check is probably unnecessary. it makes the code less readable
# readability-identifier-naming, # https://github.com/XRPLF/rippled/pull/6571
# ---
#
CheckOptions:
readability-braces-around-statements.ShortStatementLines: 2
readability-identifier-naming.MacroDefinitionCase: UPPER_CASE
readability-identifier-naming.ClassCase: CamelCase
readability-identifier-naming.StructCase: CamelCase
readability-identifier-naming.UnionCase: CamelCase
readability-identifier-naming.EnumCase: CamelCase
readability-identifier-naming.EnumConstantCase: CamelCase
readability-identifier-naming.ScopedEnumConstantCase: CamelCase
readability-identifier-naming.GlobalConstantCase: UPPER_CASE
readability-identifier-naming.GlobalConstantPrefix: "k"
readability-identifier-naming.GlobalVariableCase: CamelCase
readability-identifier-naming.GlobalVariablePrefix: "g"
readability-identifier-naming.ConstexprFunctionCase: camelBack
readability-identifier-naming.ConstexprMethodCase: camelBack
readability-identifier-naming.ClassMethodCase: camelBack
readability-identifier-naming.ClassMemberCase: camelBack
readability-identifier-naming.ClassConstantCase: UPPER_CASE
readability-identifier-naming.ClassConstantPrefix: "k"
readability-identifier-naming.StaticConstantCase: UPPER_CASE
readability-identifier-naming.StaticConstantPrefix: "k"
readability-identifier-naming.StaticVariableCase: UPPER_CASE
readability-identifier-naming.StaticVariablePrefix: "k"
readability-identifier-naming.ConstexprVariableCase: UPPER_CASE
readability-identifier-naming.ConstexprVariablePrefix: "k"
readability-identifier-naming.LocalConstantCase: camelBack
readability-identifier-naming.LocalVariableCase: camelBack
readability-identifier-naming.TemplateParameterCase: CamelCase
readability-identifier-naming.ParameterCase: camelBack
readability-identifier-naming.FunctionCase: camelBack
readability-identifier-naming.MemberCase: camelBack
readability-identifier-naming.PrivateMemberSuffix: _
readability-identifier-naming.ProtectedMemberSuffix: _
readability-identifier-naming.PublicMemberSuffix: ""
readability-identifier-naming.GlobalFunctionIgnoredRegexp: "^(to_string|hash_append|tuple_hash)$"
# readability-identifier-naming.MacroDefinitionCase: UPPER_CASE
# readability-identifier-naming.ClassCase: CamelCase
# readability-identifier-naming.StructCase: CamelCase
# readability-identifier-naming.UnionCase: CamelCase
# readability-identifier-naming.EnumCase: CamelCase
# readability-identifier-naming.EnumConstantCase: CamelCase
# readability-identifier-naming.ScopedEnumConstantCase: CamelCase
# readability-identifier-naming.GlobalConstantCase: UPPER_CASE
# readability-identifier-naming.GlobalConstantPrefix: "k"
# readability-identifier-naming.GlobalVariableCase: CamelCase
# readability-identifier-naming.GlobalVariablePrefix: "g"
# readability-identifier-naming.ConstexprFunctionCase: camelBack
# readability-identifier-naming.ConstexprMethodCase: camelBack
# readability-identifier-naming.ClassMethodCase: camelBack
# readability-identifier-naming.ClassMemberCase: camelBack
# readability-identifier-naming.ClassConstantCase: UPPER_CASE
# readability-identifier-naming.ClassConstantPrefix: "k"
# readability-identifier-naming.StaticConstantCase: UPPER_CASE
# readability-identifier-naming.StaticConstantPrefix: "k"
# readability-identifier-naming.StaticVariableCase: UPPER_CASE
# readability-identifier-naming.StaticVariablePrefix: "k"
# readability-identifier-naming.ConstexprVariableCase: UPPER_CASE
# readability-identifier-naming.ConstexprVariablePrefix: "k"
# readability-identifier-naming.LocalConstantCase: camelBack
# readability-identifier-naming.LocalVariableCase: camelBack
# readability-identifier-naming.TemplateParameterCase: CamelCase
# readability-identifier-naming.ParameterCase: camelBack
# readability-identifier-naming.FunctionCase: camelBack
# readability-identifier-naming.MemberCase: camelBack
# readability-identifier-naming.PrivateMemberSuffix: _
# readability-identifier-naming.ProtectedMemberSuffix: _
# readability-identifier-naming.PublicMemberSuffix: ""
# readability-identifier-naming.FunctionIgnoredRegexp: ".*tag_invoke.*"
bugprone-unsafe-functions.ReportMoreUnsafeFunctions: true
bugprone-unused-return-value.CheckedReturnTypes: ::std::error_code;::std::error_condition;::std::errc
misc-include-cleaner.IgnoreHeaders: ".*/(detail|impl)/.*;.*fwd\\.h(pp)?;time.h;stdlib.h;sqlite3.h;netinet/in\\.h;sys/resource\\.h;sys/sysinfo\\.h;linux/sysinfo\\.h;__chrono/.*;bits/.*;_abort\\.h;boost/uuid/uuid_hash.hpp;boost/beast/core/flat_buffer\\.hpp;boost/beast/http/field\\.hpp;boost/beast/http/dynamic_body\\.hpp;boost/beast/http/message\\.hpp;boost/beast/http/read\\.hpp;boost/beast/http/write\\.hpp;openssl/obj_mac\\.h"
HeaderFilterRegex: '^.*/(test|xrpl|xrpld)/.*\.(h|hpp|ipp)$'
#
HeaderFilterRegex: '^.*/(test|xrpl|xrpld)/.*\.(h|hpp)$'
ExcludeHeaderFilterRegex: '^.*/protocol_autogen/.*\.(h|hpp)$'
WarningsAsErrors: "*"

View File

@@ -5,8 +5,6 @@
# This file is sorted in reverse chronological order, with the most recent commits at the top.
# The commits listed here are ignored by git blame, which is useful for formatting-only commits that would otherwise obscure the history of changes to a file.
# refactor: Enable clang-tidy `readability-identifier-naming` check (#6571)
8995564ed6b9e453e144bb663303072a3c1ba305
# refactor: Enable remaining clang-tidy `cppcoreguidelines` checks (#6538)
72f4cb097f626b08b02fc3efcb4aa11cb2e7adb8
# refactor: Rename system name from 'ripple' to 'xrpld' (#6347)

43
.github/actions/print-env/action.yml vendored Normal file
View File

@@ -0,0 +1,43 @@
name: Print build environment
description: "Print environment and some tooling versions"
runs:
using: composite
steps:
- name: Check configuration (Windows)
if: ${{ runner.os == 'Windows' }}
shell: bash
run: |
echo 'Checking environment variables.'
set
- name: Check configuration (Linux and macOS)
if: ${{ runner.os == 'Linux' || runner.os == 'macOS' }}
shell: bash
run: |
echo 'Checking path.'
echo ${PATH} | tr ':' '\n'
echo 'Checking environment variables.'
env | sort
echo 'Checking compiler version.'
${{ runner.os == 'Linux' && '${CC}' || 'clang' }} --version
echo 'Checking Ninja version.'
ninja --version
echo 'Checking nproc version.'
nproc --version
- name: Check configuration (all)
shell: bash
run: |
echo 'Checking Ccache version.'
ccache --version
echo 'Checking CMake version.'
cmake --version
echo 'Checking Conan version.'
conan --version

View File

@@ -33,6 +33,17 @@ updates:
prefix: "ci: [DEPENDABOT] "
target-branch: develop
- package-ecosystem: github-actions
directory: .github/actions/print-env/
schedule:
interval: weekly
day: monday
time: "04:00"
timezone: Etc/GMT
commit-message:
prefix: "ci: [DEPENDABOT] "
target-branch: develop
- package-ecosystem: github-actions
directory: .github/actions/setup-conan/
schedule:

View File

@@ -93,7 +93,6 @@ test.core > xrpl.basics
test.core > xrpl.core
test.core > xrpld.core
test.core > xrpl.json
test.core > xrpl.protocol
test.core > xrpl.rdb
test.core > xrpl.server
test.csf > xrpl.basics
@@ -188,16 +187,10 @@ test.toplevel > xrpl.json
test.unit_test > xrpl.basics
test.unit_test > xrpl.protocol
tests.libxrpl > xrpl.basics
tests.libxrpl > xrpl.core
tests.libxrpl > xrpl.json
tests.libxrpl > xrpl.ledger
tests.libxrpl > xrpl.net
tests.libxrpl > xrpl.nodestore
tests.libxrpl > xrpl.protocol
tests.libxrpl > xrpl.protocol_autogen
tests.libxrpl > xrpl.server
tests.libxrpl > xrpl.shamap
tests.libxrpl > xrpl.tx
xrpl.conditions > xrpl.basics
xrpl.conditions > xrpl.protocol
xrpl.core > xrpl.basics

View File

@@ -62,7 +62,7 @@ ${SED_COMMAND} -i 's@ripple/@xrpld/@g' src/test/core/Config_test.cpp
${SED_COMMAND} -i 's/Rippled/File/g' src/test/core/Config_test.cpp
# Restore the old config file name in the code that maintains support for now.
${SED_COMMAND} -i 's/kCONFIG_LEGACY_NAME = "xrpld.cfg"/kCONFIG_LEGACY_NAME = "rippled.cfg"/g' src/xrpld/core/detail/Config.cpp
${SED_COMMAND} -i 's/configLegacyName = "xrpld.cfg"/configLegacyName = "rippled.cfg"/g' src/xrpld/core/detail/Config.cpp
# Restore an URL.
${SED_COMMAND} -i 's/connect-your-xrpld-to-the-xrp-test-net.html/connect-your-rippled-to-the-xrp-test-net.html/g' cfg/xrpld-example.cfg

View File

@@ -90,7 +90,7 @@ ${SED_COMMAND} -i 's/www.ripple.com/www.xrpl.org/g' src/test/protocol/Seed_test.
# Restore specific changes.
${SED_COMMAND} -i 's@b5efcc/src/xrpld@b5efcc/src/ripple@' include/xrpl/protocol/README.md
${SED_COMMAND} -i 's/dbPrefix_ = "xrpldb"/dbPrefix_ = "rippledb"/' src/xrpld/app/misc/SHAMapStoreImp.h # cspell: disable-line
${SED_COMMAND} -i 's/kCONFIG_LEGACY_NAME = "xrpld.cfg"/kCONFIG_LEGACY_NAME = "rippled.cfg"/' src/xrpld/core/detail/Config.cpp
${SED_COMMAND} -i 's/configLegacyName = "xrpld.cfg"/configLegacyName = "rippled.cfg"/' src/xrpld/core/detail/Config.cpp
popd
echo "Renaming complete."

View File

@@ -51,21 +51,20 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
# Only generate a subset of configurations in PRs.
if not all:
# Debian:
# - Bookworm using GCC 13: Debug on linux/amd64, set the reference
# fee to 500 and enable code coverage (which will be done below).
# - Bookworm using GCC 15: Debug on linux/amd64, enable Address and
# UB sanitizers (which will be done below).
# - Bookworm using GCC 13: Release on linux/amd64, set the reference
# fee to 500.
# - Bookworm using GCC 15: Debug on linux/amd64, enable code
# coverage (which will be done below).
# - Bookworm using Clang 16: Debug on linux/amd64, enable voidstar.
# - Bookworm using Clang 17: Release on linux/amd64, set the
# reference fee to 1000.
# - Bookworm using Clang 20: Debug on linux/amd64, enable Address
# and UB sanitizers (which will be done below).
# - Bookworm using Clang 20: Debug on linux/amd64.
if os["distro_name"] == "debian":
skip = True
if os["distro_version"] == "bookworm":
if (
f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-13"
and build_type == "Debug"
and build_type == "Release"
and architecture["platform"] == "linux/amd64"
):
cmake_args = f"-DUNIT_TEST_REFERENCE_FEE=500 {cmake_args}"
@@ -194,11 +193,11 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
):
continue
# Enable code coverage for Debian Bookworm using GCC 13 in Debug on
# linux/amd64.
# Enable code coverage for Debian Bookworm using GCC 15 in Debug on
# linux/amd64
if (
f"{os['distro_name']}-{os['distro_version']}" == "debian-bookworm"
and f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-13"
and f"{os['compiler_name']}-{os['compiler_version']}" == "gcc-15"
and build_type == "Debug"
and architecture["platform"] == "linux/amd64"
):
@@ -235,39 +234,23 @@ def generate_strategy_matrix(all: bool, config: Config) -> list:
# Add the configuration to the list, with the most unique fields first,
# so that they are easier to identify in the GitHub Actions UI, as long
# names get truncated.
# Add Address and UB sanitizers as separate configurations for specific
# bookworm distros. Thread sanitizer is currently disabled (see below).
# Add Address and Thread (both coupled with UB) sanitizers for specific bookworm distros.
# GCC-Asan xrpld-embedded tests are failing because of https://github.com/google/sanitizers/issues/856
if os[
"distro_version"
] == "bookworm" and f"{os['compiler_name']}-{os['compiler_version']}" in [
"gcc-15",
"clang-20",
]:
# Add ASAN configuration.
if (
os["distro_version"] == "bookworm"
and f"{os['compiler_name']}-{os['compiler_version']}" == "clang-20"
):
# Add ASAN + UBSAN configuration.
configurations.append(
{
"config_name": config_name + "-asan",
"config_name": config_name + "-asan-ubsan",
"cmake_args": cmake_args,
"cmake_target": cmake_target,
"build_only": build_only,
"build_type": build_type,
"os": os,
"architecture": architecture,
"sanitizers": "address",
}
)
# Add UBSAN configuration.
configurations.append(
{
"config_name": config_name + "-ubsan",
"cmake_args": cmake_args,
"cmake_target": cmake_target,
"build_only": build_only,
"build_type": build_type,
"os": os,
"architecture": architecture,
"sanitizers": "undefinedbehavior",
"sanitizers": "address,undefinedbehavior",
}
)
# TSAN is deactivated due to seg faults with latest compilers.

View File

@@ -58,12 +58,15 @@ jobs:
# Keep the paths below in sync with those in `on-trigger.yml`.
.github/actions/build-deps/**
.github/actions/build-test/**
.github/actions/generate-version/**
.github/actions/setup-conan/**
.github/scripts/strategy-matrix/**
.github/workflows/reusable-build.yml
.github/workflows/reusable-build-test-config.yml
.github/workflows/reusable-build-test.yml
.github/workflows/reusable-clang-tidy.yml
.github/workflows/reusable-clang-tidy-files.yml
.github/workflows/reusable-strategy-matrix.yml
.github/workflows/reusable-test.yml
.github/workflows/reusable-upload-recipe.yml
@@ -173,4 +176,4 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Fail
run: exit 1
run: false

View File

@@ -15,12 +15,15 @@ on:
# Keep the paths below in sync with those in `on-pr.yml`.
- ".github/actions/build-deps/**"
- ".github/actions/build-test/**"
- ".github/actions/generate-version/**"
- ".github/actions/setup-conan/**"
- ".github/scripts/strategy-matrix/**"
- ".github/workflows/reusable-build.yml"
- ".github/workflows/reusable-build-test-config.yml"
- ".github/workflows/reusable-build-test.yml"
- ".github/workflows/reusable-clang-tidy.yml"
- ".github/workflows/reusable-clang-tidy-files.yml"
- ".github/workflows/reusable-strategy-matrix.yml"
- ".github/workflows/reusable-test.yml"
- ".github/workflows/reusable-upload-recipe.yml"

View File

@@ -14,7 +14,7 @@ on:
jobs:
# Call the workflow in the XRPLF/actions repo that runs the pre-commit hooks.
run-hooks:
uses: XRPLF/actions/.github/workflows/pre-commit.yml@5e942d61bf32f7557a7c159cfac4712a687b3e3a
uses: XRPLF/actions/.github/workflows/pre-commit.yml@9307df762265e15c745ddcdb38a581c989f7f349
with:
runs_on: ubuntu-latest
container: '{ "image": "ghcr.io/xrplf/ci/tools-rippled-pre-commit:sha-41ec7c1" }'

View File

@@ -116,7 +116,7 @@ jobs:
run: echo "CCACHE_LOGFILE=${{ runner.temp }}/ccache.log" >> "${GITHUB_ENV}"
- name: Print build environment
uses: XRPLF/actions/print-build-env@59dec886e4afb05a1724443af08baccbc045b574
uses: ./.github/actions/print-env
- name: Get number of processors
uses: XRPLF/actions/get-nproc@cf0433aa74563aead044a1e395610c96d65a37cf

View File

@@ -0,0 +1,175 @@
name: Run clang-tidy on files
on:
workflow_call:
inputs:
files:
description: "List of files to check (empty means check all files)"
type: string
default: ""
create_issue_on_failure:
description: "Whether to create an issue if the check failed"
type: boolean
default: false
defaults:
run:
shell: bash
env:
# Conan installs the generators in the build/generators directory, see the
# layout() method in conanfile.py. We then run CMake from the build directory.
BUILD_DIR: build
BUILD_TYPE: Release
jobs:
run-clang-tidy:
name: Run clang tidy
runs-on: ["self-hosted", "Linux", "X64", "heavy"]
container: "ghcr.io/xrplf/ci/debian-trixie:clang-21-sha-53033a2"
permissions:
issues: write
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Prepare runner
uses: XRPLF/actions/prepare-runner@90f11ee655d1687824fb8793db770477d52afbab
with:
enable_ccache: false
- name: Print build environment
uses: ./.github/actions/print-env
- name: Get number of processors
uses: XRPLF/actions/get-nproc@cf0433aa74563aead044a1e395610c96d65a37cf
id: nproc
- name: Setup Conan
uses: ./.github/actions/setup-conan
- name: Build dependencies
uses: ./.github/actions/build-deps
with:
build_nproc: ${{ steps.nproc.outputs.nproc }}
build_type: ${{ env.BUILD_TYPE }}
log_verbosity: verbose
- name: Configure CMake
working-directory: ${{ env.BUILD_DIR }}
run: |
cmake \
-G 'Ninja' \
-DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake \
-DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \
-Dtests=ON \
-Dwerr=ON \
-Dxrpld=ON \
..
# clang-tidy needs headers generated from proto files
- name: Build libxrpl.libpb
working-directory: ${{ env.BUILD_DIR }}
run: |
ninja -j ${{ steps.nproc.outputs.nproc }} xrpl.libpb
- name: Run clang tidy
id: run_clang_tidy
continue-on-error: true
env:
TARGETS: ${{ inputs.files != '' && inputs.files || 'src tests' }}
run: |
run-clang-tidy -j ${{ steps.nproc.outputs.nproc }} -p "${BUILD_DIR}" -quiet -fix -allow-no-checks ${TARGETS} 2>&1 | tee clang-tidy-output.txt
- name: Upload clang-tidy output
if: ${{ github.event.repository.visibility == 'public' && steps.run_clang_tidy.outcome != 'success' }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: clang-tidy-results
path: clang-tidy-output.txt
retention-days: 30
- name: Generate git diff
if: ${{ steps.run_clang_tidy.outcome != 'success' }}
run: |
git diff | tee clang-tidy-git-diff.txt
- name: Upload clang-tidy diff output
if: ${{ github.event.repository.visibility == 'public' && steps.run_clang_tidy.outcome != 'success' }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: clang-tidy-git-diff
path: clang-tidy-git-diff.txt
retention-days: 30
- name: Create an issue
if: ${{ steps.run_clang_tidy.outcome != 'success' && inputs.create_issue_on_failure }}
id: create_issue
shell: bash
env:
GH_TOKEN: ${{ github.token }}
run: |
# Prepare issue body with clang-tidy output
cat > issue.md <<EOF
## Clang-tidy Check Failed
**Workflow:** ${{ github.workflow }}
**Run ID:** ${{ github.run_id }}
**Commit:** ${{ github.sha }}
**Branch/Ref:** ${{ github.ref }}
**Triggered by:** ${{ github.actor }}
### Clang-tidy Output:
\`\`\`
EOF
# Append clang-tidy output (filter for errors and warnings)
if [ -f clang-tidy-output.txt ]; then
# Extract lines containing 'error:', 'warning:', or 'note:'
grep -E '(error:|warning:|note:)' clang-tidy-output.txt > filtered-output.txt || true
# If filtered output is empty, use original (might be a different error format)
if [ ! -s filtered-output.txt ]; then
cp clang-tidy-output.txt filtered-output.txt
fi
# Truncate if too large
head -c 60000 filtered-output.txt >> issue.md
if [ "$(wc -c < filtered-output.txt)" -gt 60000 ]; then
echo "" >> issue.md
echo "... (output truncated, see artifacts for full output)" >> issue.md
fi
rm filtered-output.txt
else
echo "No output file found" >> issue.md
fi
cat >> issue.md <<EOF
\`\`\`
**Workflow run:** ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
---
*This issue was automatically created by the clang-tidy workflow.*
EOF
# Create the issue
gh issue create \
--label "Bug,Clang-tidy" \
--title "Clang-tidy check failed" \
--body-file ./issue.md \
> create_issue.log
created_issue="$(sed 's|.*/||' create_issue.log)"
echo "created_issue=$created_issue" >> $GITHUB_OUTPUT
echo "Created issue #$created_issue"
rm -f create_issue.log issue.md clang-tidy-output.txt
- name: Fail the workflow if clang-tidy failed
if: ${{ steps.run_clang_tidy.outcome != 'success' }}
run: |
echo "Clang-tidy check failed!"
exit 1

View File

@@ -1,4 +1,4 @@
name: Run clang-tidy on files
name: Clang-tidy check
on:
workflow_call:
@@ -16,198 +16,40 @@ defaults:
run:
shell: bash
env:
BUILD_DIR: build
BUILD_TYPE: Debug # Debug so that ASSERTS and such participate in clang-tidy check
OUTPUT_FILE: clang-tidy-output.txt
DIFF_FILE: clang-tidy-git-diff.txt
ISSUE_FILE: clang-tidy-issue.md
jobs:
determine-files:
name: Determine files to check
if: ${{ inputs.check_only_changed }}
permissions:
contents: read
uses: XRPLF/actions/.github/workflows/determine-tidy-files.yml@12f5dbc98a2260259a66970e57fa4d26fb7f285c
run-clang-tidy:
name: Run clang tidy
needs: [determine-files]
if: ${{ always() && !cancelled() && (!inputs.check_only_changed || needs.determine-files.outputs.cpp_changed_files != '' || needs.determine-files.outputs.clang_tidy_config_changed == 'true') }}
runs-on: ["self-hosted", "Linux", "X64", "heavy"]
container: "ghcr.io/xrplf/ci/debian-trixie:clang-21-sha-53033a2"
permissions:
contents: read
runs-on: ubuntu-latest
outputs:
clang_tidy_config_changed: ${{ steps.changed_clang_tidy.outputs.any_changed }}
any_cpp_changed: ${{ steps.changed_files.outputs.any_changed }}
all_changed_files: ${{ steps.changed_files.outputs.all_changed_files }}
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Prepare runner
uses: XRPLF/actions/prepare-runner@90f11ee655d1687824fb8793db770477d52afbab
- name: Get changed C++ files
id: changed_files
uses: tj-actions/changed-files@9426d40962ed5378910ee2e21d5f8c6fcbf2dd96 # v47.0.6
with:
enable_ccache: false
files: |
**/*.cpp
**/*.h
**/*.ipp
separator: " "
- name: Print build environment
uses: XRPLF/actions/print-build-env@59dec886e4afb05a1724443af08baccbc045b574
- name: Get number of processors
uses: XRPLF/actions/get-nproc@cf0433aa74563aead044a1e395610c96d65a37cf
id: nproc
- name: Setup Conan
uses: ./.github/actions/setup-conan
- name: Build dependencies
uses: ./.github/actions/build-deps
- name: Get changed clang-tidy configuration
id: changed_clang_tidy
uses: tj-actions/changed-files@9426d40962ed5378910ee2e21d5f8c6fcbf2dd96 # v47.0.6
with:
build_nproc: ${{ steps.nproc.outputs.nproc }}
build_type: ${{ env.BUILD_TYPE }}
log_verbosity: verbose
files: |
.clang-tidy
- name: Configure CMake
working-directory: ${{ env.BUILD_DIR }}
run: |
cmake \
-G 'Ninja' \
-DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake \
-DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \
-Dtests=ON \
-Dwerr=ON \
-Dxrpld=ON \
..
# clang-tidy needs headers generated from proto files
- name: Build libxrpl.libpb
working-directory: ${{ env.BUILD_DIR }}
run: |
ninja -j ${{ steps.nproc.outputs.nproc }} xrpl.libpb
- name: Run clang tidy
id: run_clang_tidy
continue-on-error: true
env:
TARGETS: ${{ (needs.determine-files.outputs.clang_tidy_config_changed != 'true' && inputs.check_only_changed) && needs.determine-files.outputs.cpp_changed_files || 'src tests' }}
run: |
set -o pipefail
run-clang-tidy -j ${{ steps.nproc.outputs.nproc }} -p "${BUILD_DIR}" -quiet -fix -allow-no-checks ${TARGETS} 2>&1 | tee "${OUTPUT_FILE}"
- name: Upload clang-tidy output
if: ${{ github.event.repository.visibility == 'public' && steps.run_clang_tidy.outcome != 'success' }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
path: ${{ env.OUTPUT_FILE }}
archive: false
retention-days: 30
- name: Generate git diff
if: ${{ steps.run_clang_tidy.outcome != 'success' }}
run: |
git diff | tee "${DIFF_FILE}"
- name: Upload clang-tidy diff output
if: ${{ github.event.repository.visibility == 'public' && steps.run_clang_tidy.outcome != 'success' }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
path: ${{ env.DIFF_FILE }}
archive: false
retention-days: 30
- name: Write issue header
if: ${{ steps.run_clang_tidy.outcome != 'success' }}
run: |
# Prepare issue body with clang-tidy output
cat > "${ISSUE_FILE}" <<EOF
## Clang-tidy Check Failed
**Workflow:** ${{ github.workflow }}
**Run ID:** ${{ github.run_id }}
**Commit:** ${{ github.sha }}
**Branch/Ref:** ${{ github.ref }}
**Triggered by:** ${{ github.actor }}
### Clang-tidy Output:
\`\`\`
EOF
- name: Append clang-tidy output to issue body
if: ${{ steps.run_clang_tidy.outcome != 'success' }}
run: |
# Append clang-tidy output (filter for errors and warnings)
if [ -f "${OUTPUT_FILE}" ]; then
# Extract lines containing 'error:', 'warning:', or 'note:'
grep -E '(error:|warning:|note:)' "${OUTPUT_FILE}" > filtered-output.txt || true
# If filtered output is empty, use original (might be a different error format)
if [ ! -s filtered-output.txt ]; then
cp "${OUTPUT_FILE}" filtered-output.txt
fi
# Truncate if too large
head -c 60000 filtered-output.txt >> "${ISSUE_FILE}"
if [ "$(wc -c < filtered-output.txt)" -gt 60000 ]; then
echo "" >> "${ISSUE_FILE}"
echo "... (output truncated, see artifacts for full output)" >> "${ISSUE_FILE}"
fi
rm filtered-output.txt
else
echo "No output file found" >> "${ISSUE_FILE}"
fi
- name: Append issue footer
if: ${{ steps.run_clang_tidy.outcome != 'success' }}
run: |
cat >> "${ISSUE_FILE}" <<EOF
\`\`\`
**Workflow run:** ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
---
*This issue was automatically created by the clang-tidy workflow.*
EOF
- name: Upload issue body artifact
if: ${{ github.event.repository.visibility == 'public' && steps.run_clang_tidy.outcome != 'success' }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
path: ${{ env.ISSUE_FILE }}
archive: false
retention-days: 30
- name: Fail if clang-tidy found issues
if: ${{ steps.run_clang_tidy.outcome != 'success' }}
run: |
echo "Clang-tidy check failed!"
exit 1
create-issue-on-failure:
name: Create GitHub issue on failure
runs-on: ubuntu-latest
needs: [run-clang-tidy]
if: ${{ always() && !cancelled() && inputs.create_issue_on_failure && needs.run-clang-tidy.result == 'failure' && github.event.repository.visibility == 'public' }}
permissions:
issues: write
contents: read
steps:
- name: Download clang-tidy-issue.md
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: ${{ env.ISSUE_FILE }}
- name: Create GitHub issue
env:
GH_TOKEN: ${{ github.token }}
run: |
# Create the issue
gh issue create \
--label "Bug,Clang-tidy" \
--title "Clang-tidy check failed" \
--body-file ./"${ISSUE_FILE}" \
> create_issue.log
- name: Output created issue number
run: |
created_issue="$(sed 's|.*/||' create_issue.log)"
echo "created_issue=$created_issue" >> $GITHUB_OUTPUT
echo "Created issue #$created_issue"
run-clang-tidy:
needs: [determine-files]
if: ${{ always() && !cancelled() && (!inputs.check_only_changed || needs.determine-files.outputs.any_cpp_changed == 'true' || needs.determine-files.outputs.clang_tidy_config_changed == 'true') }}
uses: ./.github/workflows/reusable-clang-tidy-files.yml
with:
files: ${{ (needs.determine-files.outputs.clang_tidy_config_changed != 'true' && inputs.check_only_changed) && needs.determine-files.outputs.all_changed_files || '' }}
create_issue_on_failure: ${{ inputs.create_issue_on_failure }}

View File

@@ -75,7 +75,7 @@ jobs:
enable_ccache: false
- name: Print build environment
uses: XRPLF/actions/print-build-env@59dec886e4afb05a1724443af08baccbc045b574
uses: ./.github/actions/print-env
- name: Get number of processors
uses: XRPLF/actions/get-nproc@cf0433aa74563aead044a1e395610c96d65a37cf

View File

@@ -28,8 +28,6 @@ This section contains changes targeting a future version.
### Additions
- `ledger_entry`, `account_objects`: The `Delegate` ledger entry now includes an optional `DestinationNode` field, which stores the index into the authorized account's owner directory. This field is present on entries created after bidirectional directory tracking was introduced and may appear in RPC responses for those entries. ([#6681](https://github.com/XRPLF/rippled/pull/6681))
- `server_definitions`: Added the following new sections to the response ([#6321](https://github.com/XRPLF/rippled/pull/6321)):
- `TRANSACTION_FORMATS`: Describes the fields and their optionality for each transaction type, including common fields shared across all transactions.
- `LEDGER_ENTRY_FORMATS`: Describes the fields and their optionality for each ledger entry type, including common fields shared across all ledger entries.
@@ -42,14 +40,6 @@ This section contains changes targeting a future version.
- Peer Crawler: The `port` field in `overlay.active[]` now consistently returns an integer instead of a string for outbound peers. [#6318](https://github.com/XRPLF/rippled/pull/6318)
- `ping`: The `ip` field is no longer returned as an empty string for proxied connections without a forwarded-for header. It is now omitted, consistent with the behavior for identified connections. [#6730](https://github.com/XRPLF/rippled/pull/6730)
- gRPC `GetLedgerDiff`: Fixed error message that incorrectly said "base ledger not validated" when the desired ledger was not validated. [#6730](https://github.com/XRPLF/rippled/pull/6730)
- `account_channels`: The `destination_account` field now returns an error if the value is not a string. [#6529](https://github.com/XRPLF/rippled/pull/6529)
- `subscribe`: The `taker` field in the `books` array now returns an error if the value is not a string. [#6529](https://github.com/XRPLF/rippled/pull/6529)
- `account_info`: The `urlgravatar` field now uses HTTPS instead of HTTP. [#6529](https://github.com/XRPLF/rippled/pull/6529)
- `ledger`: The `full`, `accounts`, `transactions`, `expand`, `binary`, `owner_funds`, and `queue` fields now return an error if the value is not a boolean. [#6529](https://github.com/XRPLF/rippled/pull/6529)
- `ledger_data`: The `binary` field now returns an error if the value is not a boolean. [#6529](https://github.com/XRPLF/rippled/pull/6529)
- `submit`: The `fail_hard` field now returns an error if the value is not a boolean. [#6529](https://github.com/XRPLF/rippled/pull/6529)
- `subscribe`: The `taker` field in the `books` array now returns `actMalformed` instead of `badIssuer` if the value is not a valid account. [#6529](https://github.com/XRPLF/rippled/pull/6529)
- Fixed a bug in `Forwarded` HTTP header parsing where the extracted IP address could be incorrect when no comma or semicolon delimiter follows the address. This could cause the server to misidentify a client's IP address when operating behind a reverse proxy. [#6529](https://github.com/XRPLF/rippled/pull/6529)
## XRP Ledger server version 3.1.0

View File

@@ -348,8 +348,8 @@ For this reason:
- Contract description for `UNREACHABLE` should describe the _unexpected_
situation which caused the line to have been reached.
- Example good name for an
`UNREACHABLE` macro `"json::operator==(Value, Value) : invalid type"`; example
good name for an `XRPL_ASSERT` macro `"json::Value::asCString : valid type"`.
`UNREACHABLE` macro `"Json::operator==(Value, Value) : invalid type"`; example
good name for an `XRPL_ASSERT` macro `"Json::Value::asCString : valid type"`.
- Example **bad** name
`"RFC1751::insert(char* s, int x, int start, int length) : length is greater than or equal zero"`
(missing namespace, unnecessary full function signature, description too verbose).

View File

@@ -22,10 +22,117 @@ Responsible investigation includes, but isn't limited to, the following:
- Not targeting physical security measures, or attempting to use social engineering, spam, distributed denial of service (DDOS) attacks, etc.
- Investigating bugs in a way that makes a reasonable, good faith effort not to be disruptive or harmful to the XRP Ledger and the broader ecosystem.
### Responsible Disclosure
If you discover a vulnerability or potential threat, or if you _think_
you have, please reach out by dropping an email using the contact
information below.
Your report should include the following:
- Your contact information (typically, an email address);
- The description of the vulnerability;
- The attack scenario (if any);
- The steps to reproduce the vulnerability;
- Any other relevant details or artifacts, including code, scripts or patches.
In your email, please describe the issue or potential threat. If possible, include a "repro" (code that can reproduce the issue) or describe the best way to reproduce and replicate the issue. Please make your report as detailed and comprehensive as possible.
For more information on responsible disclosure, please read this [Wikipedia article](https://en.wikipedia.org/wiki/Responsible_disclosure).
## Report Handling Process
Please report the bug directly to us and limit further disclosure. If you want to prove that you knew the bug as of a given time, consider using a cryptographic pre-commitment: hash the content of your report and publish the hash on a medium of your choice (e.g. on Twitter or as a memo in a transaction) as "proof" that you had written the text at a given point in time.
Once we receive a report, we:
1. Assign two people to independently evaluate the report;
2. Consider their recommendations;
3. If action is necessary, formulate a plan to address the issue;
4. Communicate privately with the reporter to explain our plan.
5. Prepare, test and release a version which fixes the issue; and
6. Announce the vulnerability publicly.
We will triage and respond to your disclosure within 24 hours. Beyond that, we will work to analyze the issue in more detail, formulate, develop and test a fix.
While we commit to responding with 24 hours of your initial report with our triage assessment, we cannot guarantee a response time for the remaining steps. We will communicate with you throughout this process, letting you know where we are and keeping you updated on the timeframe.
## Bug Bounty Program
[Ripple](https://ripple.com) is generously sponsoring a bug bounty program for vulnerabilities in [`xrpld`](https://github.com/XRPLF/rippled) (and other related projects, like [`Clio`](https://github.com/XRPLF/clio), [`xrpl.js`](https://github.com/XRPLF/xrpl.js), [`xrpl-py`](https://github.com/XRPLF/xrpl-py), [`xrpl4j`](https://github.com/XRPLF/xrpl4j)).
[Ripple](https://ripple.com) is generously sponsoring a bug bounty program for vulnerabilities in [`xrpld`](https://github.com/XRPLF/rippled) (and other related projects, like [`xrpl.js`](https://github.com/XRPLF/xrpl.js), [`xrpl-py`](https://github.com/XRPLF/xrpl-py), [`xrpl4j`](https://github.com/XRPLF/xrpl4j)).
This program allows us to recognize and reward individuals or groups that identify and report bugs.
This program allows us to recognize and reward individuals or groups that identify and report bugs. In summary, in order to qualify for a bounty, the bug must be:
We have partnered with Bugcrowd to manage this program. It is a private program, and security researchers can participate based on invitation. If you need access to the program, please email bugs@ripple.com with your Bugcrowd handle or Bugcrowd registered email, and we will get you added to the program. Once you have been added, please submit vulnerability reports through Bugcrowd, not by email. The detailed bug bounty policy is available on the Bugcrowd website.
1. **In scope**. Only bugs in software under the scope of the program qualify. Currently, that means `xrpld`, `xrpl.js`, `xrpl-py`, `xrpl4j`.
2. **Relevant**. A security issue, posing a danger to user funds, privacy, or the operation of the XRP Ledger.
3. **Original and previously unknown**. Bugs that are already known and discussed in public do not qualify. Previously reported bugs, even if publicly unknown, are not eligible.
4. **Specific**. We welcome general security advice or recommendations, but we cannot pay bounties for that.
5. **Fixable**. There has to be something we can do to permanently fix the problem. Note that bugs in other peoples software may still qualify in some cases. For example, if you find a bug in a library that we use which can compromise the security of software that is in scope and we can get it fixed, you may qualify for a bounty.
6. **Unused**. If you use the exploit to attack the XRP Ledger, you do not qualify for a bounty. If you report a vulnerability used in an ongoing or past attack and there is specific, concrete evidence that suggests you are the attacker we reserve the right not to pay a bounty.
The amount paid varies dramatically. Vulnerabilities that are harmless on their own, but could form part of a critical exploit will usually receive a bounty. Full-blown exploits can receive much higher bounties. Please dont hold back partial vulnerabilities while trying to construct a full-blown exploit. We will pay a bounty to anyone who reports a complete chain of vulnerabilities even if they have reported each component of the exploit separately and those vulnerabilities have been fixed in the meantime. However, to qualify for a the full bounty, you must to have been the first to report each of the partial exploits.
### Contacting Us
To report a qualifying bug, please send a detailed report to:
| Email Address | bugs@ripple.com |
| :-----------: | :-------------------------------------------------- |
| Short Key ID | `0xA9F514E0` |
| Long Key ID | `0xD900855AA9F514E0` |
| Fingerprint | `B72C 0654 2F2A E250 2763 A268 D900 855A A9F5 14E0` |
The full PGP key for this address, which is also available on several key servers (e.g. on [keyserver.ubuntu.com](https://keyserver.ubuntu.com)), is:
```
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQINBGkSZAQBEACprU199OhgdsOsygNjiQV4msuN3vDOUooehL+NwfsGfW79Tbqq
Q2u7uQ3NZjW+M2T4nsDwuhkr7pe7xSReR5W8ssaczvtUyxkvbMClilcgZ2OSCAuC
N9tzJsqOqkwBvXoNXkn//T2jnPz0ZU2wSF+NrEibq5FeuyGdoX3yXXBxq9pW9HzK
HkQll63QSl6BzVSGRQq+B6lGgaZGLwf3mzmIND9Z5VGLNK2jKynyz9z091whNG/M
kV+E7/r/bujHk7WIVId07G5/COTXmSr7kFnNEkd2Umw42dkgfiNKvlmJ9M7c1wLK
KbL9Eb4ADuW6rRc5k4s1e6GT8R4/VPliWbCl9SE32hXH8uTkqVIFZP2eyM5WRRHs
aKzitkQG9UK9gcb0kdgUkxOvvgPHAe5IuZlcHFzU4y0dBbU1VEFWVpiLU0q+IuNw
5BRemeHc59YNsngkmAZ+/9zouoShRusZmC8Wzotv75C2qVBcjijPvmjWAUz0Zunm
Lsr+O71vqHE73pERjD07wuD/ISjiYRYYE/bVrXtXLZijC7qAH4RE3nID+2ojcZyO
/2jMQvt7un56RsGH4UBHi3aBHi9bUoDGCXKiQY981cEuNaOxpou7Mh3x/ONzzSvk
sTV6nl1LOZHykN1JyKwaNbTSAiuyoN+7lOBqbV04DNYAHL88PrT21P83aQARAQAB
tB1SaXBwbGUgTGFicyA8YnVnc0ByaXBwbGUuY29tPokCTgQTAQgAOBYhBLcsBlQv
KuJQJ2OiaNkAhVqp9RTgBQJpEmQEAhsDBQsJCAcCBhUKCQgLAgQWAgMBAh4BAheA
AAoJENkAhVqp9RTgBzgP/i7y+aDWl1maig1XMdyb+o0UGusumFSW4Hmj278wlKVv
usgLPihYgHE0PKrv6WRyKOMC1tQEcYYN93M+OeQ1vFhS2YyURq6RCMmh4zq/awXG
uZbG36OURB5NH8lGBOHiN/7O+nY0CgenBT2JWm+GW3nEOAVOVm4+r5GlpPlv+Dp1
NPBThcKXFMnH73++NpSQoDzTfRYHPxhDAX3jkLi/moXfSanOLlR6l94XNNN0jBHW
Quao0rzf4WSXq9g6AS224xhAA5JyIcFl8TX7hzj5HaFn3VWo3COoDu4U7H+BM0fl
85yqiMQypp7EhN2gxpMMWaHY5TFM85U/bFXFYfEgihZ4/gt4uoIzsNI9jlX7mYvG
KFdDij+oTlRsuOxdIy60B3dKcwOH9nZZCz0SPsN/zlRWgKzK4gDKdGhFkU9OlvPu
94ZqscanoiWKDoZkF96+sjgfjkuHsDK7Lwc1Xi+T4drHG/3aVpkYabXox+lrKB/S
yxZjeqOIQzWPhnLgCaLyvsKo5hxKzL0w3eURu8F3IS7RgOOlljv4M+Me9sEVcdNV
aN3/tQwbaomSX1X5D5YXqhBwC3rU3wXwamsscRTGEpkV+JCX6KUqGP7nWmxCpAly
FL05XuOd5SVHJjXLeuje0JqLUpN514uL+bThWwDbDTdAdwW3oK/2WbXz7IfJRLBj
uQINBGkSZAQBEADdI3SL2F72qkrgFqXWE6HSRBu9bsAvTE5QrRPWk7ux6at537r4
S4sIw2dOwLvbyIrDgKNq3LQ5wCK88NO/NeCOFm4AiCJSl3pJHXYnTDoUxTrrxx+o
vSRI4I3fHEql/MqzgiAb0YUezjgFdh3vYheMPp/309PFbOLhiFqEcx80Mx5h06UH
gDzu1qNj3Ec+31NLic5zwkrAkvFvD54d6bqYR3SEgMau6aYEewpGHbWBi2pLqSi2
lQcAeOFixqGpTwDmAnYR8YtjBYepy0MojEAdTHcQQlOYSDk4q4elG+io2N8vECfU
rD6ORecN48GXdZINYWTAdslrUeanmBdgQrYkSpce8TSghgT9P01SNaXxmyaehVUO
lqI4pcg5G2oojAE8ncNS3TwDtt7daTaTC3bAdr4PXDVAzNAiewjMNZPB7xidkDGQ
Y4W1LxTMXyJVWxehYOH7tsbBRKninlfRnLgYzmtIbNRAAvNcsxU6ihv3AV0WFknN
YbSzotEv1Xq/5wk309x8zCDe+sP0cQicvbXafXmUzPAZzeqFg+VLFn7F9MP1WGlW
B1u7VIvBF1Mp9Nd3EAGBAoLRdRu+0dVWIjPTQuPIuD9cCatJA0wVaKUrjYbBMl88
a12LixNVGeSFS9N7ADHx0/o7GNT6l88YbaLP6zggUHpUD/bR+cDN7vllIQARAQAB
iQI2BBgBCAAgFiEEtywGVC8q4lAnY6Jo2QCFWqn1FOAFAmkSZAQCGwwACgkQ2QCF
Wqn1FOAfAA/8CYq4p0p4bobY20CKEMsZrkBTFJyPDqzFwMeTjgpzqbD7Y3Qq5QCK
OBbvY02GWdiIsNOzKdBxiuam2xYP9WHZj4y7/uWEvT0qlPVmDFu+HXjoJ43oxwFd
CUp2gMuQ4cSL3X94VRJ3BkVL+tgBm8CNY0vnTLLOO3kum/R69VsGJS1JSGUWjNM+
4qwS3mz+73xJu1HmERyN2RZF/DGIZI2PyONQQ6aH85G1Dd2ohu2/DBAkQAMBrPbj
FrbDaBLyFhODxU3kTWqnfLlaElSm2EGdIU2yx7n4BggEa//NZRMm5kyeo4vzhtlQ
YIVUMLAOLZvnEqDnsLKp+22FzNR/O+htBQC4lPywl53oYSALdhz1IQlcAC1ru5KR
XPzhIXV6IIzkcx9xNkEclZxmsuy5ERXyKEmLbIHAlzFmnrldlt2ZgXDtzaorLmxj
klKibxd5tF50qOpOivz+oPtFo7n+HmFa1nlVAMxlDCUdM0pEVeYDKI5zfVwalyhZ
NnjpakdZSXMwgc7NP/hH9buF35hKDp7EckT2y3JNYwHsDdy1icXN2q40XZw5tSIn
zkPWdu3OUY8PISohN6Pw4h0RH4ZmoX97E8sEfmdKaT58U4Hf2aAv5r9IWCSrAVqY
u5jvac29CzQR9Kal0A+8phHAXHNFD83SwzIC0syaT9ficAguwGH8X6Q=
=nGuD
-----END PGP PUBLIC KEY BLOCK-----
```

View File

@@ -118,7 +118,7 @@ if(MSVC)
NOMINMAX
# TODO: Resolve these warnings, don't just silence them
_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS
$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CONFIG:Debug>>:_CRTDBG_MAP_ALLOC>
$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CONFIG:Debug>,$<NOT:$<BOOL:${is_ci}>>>:_CRTDBG_MAP_ALLOC>
)
target_link_libraries(common INTERFACE -errorreport:none -machine:X64)
else()

View File

@@ -23,6 +23,7 @@ target_compile_definitions(
BOOST_FILESYSTEM_NO_DEPRECATED
>
$<$<NOT:$<BOOL:${boost_show_deprecated}>>:
BOOST_COROUTINES2_NO_DEPRECATION_WARNING
BOOST_BEAST_ALLOW_DEPRECATED
BOOST_FILESYSTEM_DEPRECATED
>

View File

@@ -34,12 +34,10 @@
* -fsanitize=<types>: Links sanitizer runtime libraries
* -mcmodel=large/medium: (GCC only) Matches compile-time code model
- SANITIZERS_RELOCATION_FLAGS: (GCC only, x86_64 only) Code model flags for linking.
- SANITIZERS_RELOCATION_FLAGS: (GCC only) Code model flags for linking.
Used to handle large instrumented binaries on x86_64:
* -mcmodel=large: For AddressSanitizer (prevents relocation errors)
* -mcmodel=medium: For ThreadSanitizer (large model is incompatible)
On ARM64, these flags are omitted since GCC does not support
-mcmodel=large with -fPIC, and -mcmodel=medium does not exist.
#]===================================================================]
include(CompilationEnv)
@@ -153,11 +151,9 @@ if(is_gcc)
elseif(enable_tsan)
# GCC doesn't support atomic_thread_fence with tsan. Suppress warnings.
list(APPEND SANITIZERS_COMPILE_FLAGS "-Wno-tsan")
if(is_amd64)
message(STATUS " Using medium code model (-mcmodel=medium)")
list(APPEND SANITIZERS_COMPILE_FLAGS "-mcmodel=medium")
list(APPEND SANITIZERS_RELOCATION_FLAGS "-mcmodel=medium")
endif()
message(STATUS " Using medium code model (-mcmodel=medium)")
list(APPEND SANITIZERS_COMPILE_FLAGS "-mcmodel=medium")
list(APPEND SANITIZERS_RELOCATION_FLAGS "-mcmodel=medium")
endif()
# Join sanitizer flags with commas for -fsanitize option

View File

@@ -152,10 +152,10 @@ def parse_sfields_macro(sfields_path):
def create_field_list_parser():
"""Create a pyparsing parser for field lists like '({...})'."""
# A field identifier (e.g., sfDestination, SoeRequired, SoeMptSupported)
# A field identifier (e.g., sfDestination, soeREQUIRED, soeMPTSupported)
field_identifier = pp.Word(pp.alphas + "_", pp.alphanums + "_")
# A single field definition: {sfName, SoeRequired, ...}
# A single field definition: {sfName, soeREQUIRED, ...}
# Allow optional trailing comma inside the braces
field_def = (
pp.Suppress("{")
@@ -185,8 +185,8 @@ def parse_field_list(fields_str):
Args:
fields_str: A string like '({
{sfDestination, SoeRequired},
{sfAmount, SoeRequired, SoeMptSupported}
{sfDestination, soeREQUIRED},
{sfAmount, soeREQUIRED, soeMPTSupported}
})'
Returns:
@@ -205,7 +205,7 @@ def parse_field_list(fields_str):
field_name = field_parts[0]
requirement = field_parts[1]
flags = list(field_parts[2:]) if len(field_parts) > 2 else []
supports_mpt = "SoeMptSupported" in flags
supports_mpt = "soeMPTSupported" in flags
fields.append(
{

View File

@@ -52,13 +52,13 @@ public:
% if field.get('mpt_support'):
* MPT Support: ${field['mpt_support']}
% endif
% if field['requirement'] == 'SoeRequired':
% if field['requirement'] == 'soeREQUIRED':
* @return The field value.
% else:
* @return The field value, or std::nullopt if not present.
% endif
*/
% if field['requirement'] == 'SoeRequired':
% if field['requirement'] == 'soeREQUIRED':
[[nodiscard]]
${field['typeData']['return_type']}
get${field['name'][2:]}() const
@@ -94,13 +94,13 @@ public:
* MPT Support: ${field['mpt_support']}
% endif
* @note This is an untyped field (${field.get('cppType', 'unknown')}).
% if field['requirement'] == 'SoeRequired':
% if field['requirement'] == 'soeREQUIRED':
* @return The field value.
% else:
* @return The field value, or std::nullopt if not present.
% endif
*/
% if field['requirement'] == 'SoeRequired':
% if field['requirement'] == 'soeREQUIRED':
[[nodiscard]]
${field['typeData']['return_type']}
get${field['name'][2:]}() const
@@ -133,13 +133,13 @@ public:
};
<%
required_fields = [f for f in fields if f['requirement'] == 'SoeRequired']
required_fields = [f for f in fields if f['requirement'] == 'soeREQUIRED']
%>\
/**
* @brief Builder for ${name} ledger entries.
*
* Provides a fluent interface for constructing ledger entries with method chaining.
* Uses STObject internally for flexible ledger entry construction.
* Uses Json::Value internally for flexible ledger entry construction.
* Inherits common field setters from LedgerEntryBuilderBase.
*/
class ${name}Builder : public LedgerEntryBuilderBase<${name}Builder>

View File

@@ -1,7 +1,7 @@
// Auto-generated unit tests for ledger entry ${name}
<%
required_fields = [f for f in fields if f["requirement"] == "SoeRequired"]
optional_fields = [f for f in fields if f["requirement"] != "SoeRequired"]
required_fields = [f for f in fields if f["requirement"] == "soeREQUIRED"]
optional_fields = [f for f in fields if f["requirement"] != "soeREQUIRED"]
def canonical_expr(field):
return f"canonical_{field['stiSuffix']}()"

View File

@@ -54,13 +54,13 @@ public:
% if field.get('supports_mpt'):
* @note This field supports MPT (Multi-Purpose Token) amounts.
% endif
% if field['requirement'] == 'SoeRequired':
% if field['requirement'] == 'soeREQUIRED':
* @return The field value.
% else:
* @return The field value, or std::nullopt if not present.
% endif
*/
% if field['requirement'] == 'SoeRequired':
% if field['requirement'] == 'soeREQUIRED':
[[nodiscard]]
${field['typeData']['return_type']}
get${field['name'][2:]}() const
@@ -97,13 +97,13 @@ public:
* @note This field supports MPT (Multi-Purpose Token) amounts.
% endif
* @note This is an untyped field.
% if field['requirement'] == 'SoeRequired':
% if field['requirement'] == 'soeREQUIRED':
* @return The field value.
% else:
* @return The field value, or std::nullopt if not present.
% endif
*/
% if field['requirement'] == 'SoeRequired':
% if field['requirement'] == 'soeREQUIRED':
[[nodiscard]]
${field['typeData']['return_type']}
get${field['name'][2:]}() const
@@ -136,13 +136,13 @@ public:
};
<%
required_fields = [f for f in fields if f['requirement'] == 'SoeRequired']
required_fields = [f for f in fields if f['requirement'] == 'soeREQUIRED']
%>\
/**
* @brief Builder for ${name} transactions.
*
* Provides a fluent interface for constructing transactions with method chaining.
* Uses STObject internally for flexible transaction construction.
* Uses Json::Value internally for flexible transaction construction.
* Inherits common field setters from TransactionBuilderBase.
*/
class ${name}Builder : public TransactionBuilderBase<${name}Builder>

View File

@@ -1,7 +1,7 @@
// Auto-generated unit tests for transaction ${name}
<%
required_fields = [f for f in fields if f["requirement"] == "SoeRequired"]
optional_fields = [f for f in fields if f["requirement"] != "SoeRequired"]
required_fields = [f for f in fields if f["requirement"] == "soeREQUIRED"]
optional_fields = [f for f in fields if f["requirement"] != "soeREQUIRED"]
def canonical_expr(field):
return f"canonical_{field['stiSuffix']}()"
@@ -33,7 +33,7 @@ TEST(Transactions${name}Tests, BuilderSettersRoundTrip)
{
// Generate a deterministic keypair for signing
auto const [publicKey, secretKey] =
generateKeyPair(KeyType::Secp256k1, generateSeed("test${name}"));
generateKeyPair(KeyType::secp256k1, generateSeed("test${name}"));
// Common transaction fields
auto const accountValue = calcAccountID(publicKey);
@@ -101,7 +101,7 @@ TEST(Transactions${name}Tests, BuilderFromStTxRoundTrip)
{
// Generate a deterministic keypair for signing
auto const [publicKey, secretKey] =
generateKeyPair(KeyType::Secp256k1, generateSeed("test${name}FromTx"));
generateKeyPair(KeyType::secp256k1, generateSeed("test${name}FromTx"));
// Common transaction fields
auto const accountValue = calcAccountID(publicKey);
@@ -168,7 +168,7 @@ TEST(Transactions${name}Tests, WrapperThrowsOnWrongTxType)
{
// Build a valid transaction of a different type
auto const [pk, sk] =
generateKeyPair(KeyType::Secp256k1, generateSeed("testWrongType"));
generateKeyPair(KeyType::secp256k1, generateSeed("testWrongType"));
auto const account = calcAccountID(pk);
% if wrong_tx_include == "AccountSet":
@@ -186,7 +186,7 @@ TEST(Transactions${name}Tests, BuilderThrowsOnWrongTxType)
{
// Build a valid transaction of a different type
auto const [pk, sk] =
generateKeyPair(KeyType::Secp256k1, generateSeed("testWrongTypeBuilder"));
generateKeyPair(KeyType::secp256k1, generateSeed("testWrongTypeBuilder"));
auto const account = calcAccountID(pk);
% if wrong_tx_include == "AccountSet":
@@ -205,7 +205,7 @@ TEST(Transactions${name}Tests, OptionalFieldsReturnNullopt)
{
// Generate a deterministic keypair for signing
auto const [publicKey, secretKey] =
generateKeyPair(KeyType::Secp256k1, generateSeed("test${name}Nullopt"));
generateKeyPair(KeyType::secp256k1, generateSeed("test${name}Nullopt"));
// Common transaction fields
auto const accountValue = calcAccountID(publicKey);

View File

@@ -4,6 +4,7 @@
"zlib/1.3.1#cac0f6daea041b0ccf42934163defb20%1774439233.809",
"xxhash/0.8.3#681d36a0a6111fc56e5e45ea182c19cc%1765850149.987",
"sqlite3/3.51.0#66aa11eabd0e34954c5c1c061ad44abe%1774467355.988",
"spdlog/1.17.0#bcbaaf7147bda6ad24ffbd1ac3d7142c%1768312128.781",
"soci/4.0.3#fe32b9ad5eb47e79ab9e45a68f363945%1774450067.231",
"snappy/1.1.10#968fef506ff261592ec30c574d4a7809%1765850147.878",
"secp256k1/0.7.1#481881709eb0bdd0185a12b912bbe8ad%1770910500.329",
@@ -11,14 +12,15 @@
"re2/20251105#8579cfd0bda4daf0683f9e3898f964b4%1774398111.888",
"protobuf/6.33.5#d96d52ba5baaaa532f47bda866ad87a5%1774467363.12",
"openssl/3.6.1#e6399de266349245a4542fc5f6c71552%1774458290.139",
"nudb/2.0.9#11149c73f8f2baff9a0198fe25971fc7%1774883011.384",
"nudb/2.0.9#11149c73f8f2baff9a0198fe25971fc7%1775040983.408",
"lz4/1.10.0#59fc63cac7f10fbe8e05c7e62c2f3504%1765850143.914",
"libiconv/1.17#1e65319e945f2d31941a9d28cc13c058%1765842973.492",
"libbacktrace/cci.20210118#a7691bfccd8caaf66309df196790a5a1%1765842973.03",
"libarchive/3.8.1#ffee18995c706e02bf96e7a2f7042e0d%1765850144.736",
"jemalloc/5.3.0#e951da9cf599e956cebc117880d2d9f8%1729241615.244",
"jemalloc/5.3.0#c671e612af76700db5957c9857978a1c%1776700030.961",
"gtest/1.17.0#5224b3b3ff3b4ce1133cbdd27d53ee7d%1768312129.152",
"grpc/1.78.1#b1a9e74b145cc471bed4dc64dc6eb2c1%1774467387.342",
"fmt/12.1.0#50abab23274d56bb8f42c94b3b9a40c7%1763984116.926",
"ed25519/2015.03#ae761bdc52730a843f0809bdf6c1b1f6%1765850143.772",
"date/3.0.4#862e11e80030356b53c2c38599ceb32b%1765850143.772",
"c-ares/1.34.6#545240bb1c40e2cacd4362d6b8967650%1774439234.681",

View File

@@ -1,6 +1,5 @@
include(default)
{% set compiler, version, compiler_exe = detect_api.detect_default_compiler() %}
{% set arch = detect_api.detect_arch() %}
{% set sanitizers = os.getenv("SANITIZERS") %}
[conf]
@@ -14,16 +13,12 @@ include(default)
{% if "address" in sanitizers %}
{% set _ = sanitizer_list.append("address") %}
{% if arch == "x86_64" %}
{% set model_code = "-mcmodel=large" %}
{% endif %}
{% set model_code = "-mcmodel=large" %}
{% set _ = defines.append("BOOST_USE_ASAN")%}
{% set _ = defines.append("BOOST_USE_UCONTEXT")%}
{% elif "thread" in sanitizers %}
{% set _ = sanitizer_list.append("thread") %}
{% if arch == "x86_64" %}
{% set model_code = "-mcmodel=medium" %}
{% endif %}
{% set model_code = "-mcmodel=medium" %}
{% set _ = extra_cxxflags.append("-Wno-tsan") %}
{% set _ = defines.append("BOOST_USE_TSAN")%}
{% set _ = defines.append("BOOST_USE_UCONTEXT")%}
@@ -87,12 +82,5 @@ tools.info.package_id:confs+=["tools.build:cxxflags", "tools.build:exelinkflags"
boost/*:without_context=False
# Boost stacktrace fails to build with some sanitizers
boost/*:without_stacktrace=True
{% elif "thread" in sanitizers %}
# Build Boost.Context with ucontext backend for TSAN. fcontext (assembly)
# has no TSAN annotations, so without this the BOOST_USE_TSAN/BOOST_USE_UCONTEXT
# defines in [conf] would be ineffective.
boost/*:extra_b2_flags=context-impl=ucontext thread-sanitizer=on define=BOOST_USE_TSAN=1
boost/*:without_context=False
boost/*:without_stacktrace=True
{% endif %}
{% endif %}

View File

@@ -35,6 +35,7 @@ class Xrpl(ConanFile):
"openssl/3.6.1",
"secp256k1/0.7.1",
"soci/4.0.3",
"spdlog/1.17.0",
"zlib/1.3.1",
]
@@ -109,6 +110,7 @@ class Xrpl(ConanFile):
"secp256k1/*:shared": False,
"snappy/*:shared": False,
"soci/*:shared": False,
"spdlog/*:shared": False,
"soci/*:with_sqlite3": True,
"soci/*:with_boost": True,
"xxhash/*:shared": False,
@@ -129,6 +131,12 @@ class Xrpl(ConanFile):
if self.settings.compiler in ["clang", "gcc"]:
self.options["boost"].without_cobalt = True
# Check if environment variable exists
if "SANITIZERS" in os.environ:
sanitizers = os.environ["SANITIZERS"]
if "address" in sanitizers.lower():
self.default_options["fPIC"] = False
def requirements(self):
self.requires("boost/1.90.0", force=True, transitive_headers=True)
self.requires("date/3.0.4", transitive_headers=True)
@@ -213,6 +221,7 @@ class Xrpl(ConanFile):
"protobuf::libprotobuf",
"soci::soci",
"secp256k1::secp256k1",
"spdlog::spdlog",
"sqlite3::sqlite",
"xxhash::xxhash",
"zlib::zlib",

View File

@@ -151,7 +151,6 @@ words:
- lseq
- lsmf
- ltype
- mathbunnyru
- mcmodel
- MEMORYSTATUSEX
- MPTAMM

View File

@@ -98,7 +98,7 @@ export LSAN_OPTIONS="include=sanitizers/suppressions/runtime-lsan-options.txt:su
**Why `detect_container_overflow=0`?**
- Boost intrusive containers (used in `AgedUnorderedContainer`) trigger false positives
- Boost intrusive containers (used in `aged_unordered_container`) trigger false positives
- Boost context switching (used in `Workers.cpp`) confuses ASAN's stack tracking
- Since we usually don't build Boost (because we don't want to instrument Boost and detect issues in Boost code) with ASAN but use Boost containers in ASAN instrumented xrpld code, it generates false positives.
- Building dependencies with ASAN instrumentation reduces false positives. But we don't want to instrument dependencies like Boost with ASAN because it is slow (to compile as well as run tests) and not necessary.

View File

@@ -477,7 +477,7 @@ struct Ledger
// The parent ledger's close time
NetClock::time_point parentCloseTime() const;
json::Value getJson() const;
Json::Value getJson() const;
//... implementation specific
};

View File

@@ -27,7 +27,7 @@ private:
std::unordered_map<std::string, std::string> lookup_;
std::vector<std::string> lines_;
std::vector<std::string> values_;
bool hadTrailingComments_ = false;
bool had_trailing_comments_ = false;
using const_iterator = decltype(lookup_)::const_iterator;
@@ -36,7 +36,7 @@ public:
explicit Section(std::string name = "");
/** Returns the name of this section. */
[[nodiscard]] std::string const&
std::string const&
name() const
{
return name_;
@@ -45,7 +45,7 @@ public:
/** Returns all the lines in the section.
This includes everything.
*/
[[nodiscard]] std::vector<std::string> const&
std::vector<std::string> const&
lines() const
{
return lines_;
@@ -54,7 +54,7 @@ public:
/** Returns all the values in the section.
Values are non-empty lines which are not key/value pairs.
*/
[[nodiscard]] std::vector<std::string> const&
std::vector<std::string> const&
values() const
{
return values_;
@@ -82,7 +82,7 @@ public:
* @return The retrieved value. A section with an empty legacy value returns
an empty string.
*/
[[nodiscard]] std::string
std::string
legacy() const
{
if (lines_.empty())
@@ -117,11 +117,11 @@ public:
}
/** Returns `true` if a key with the given name exists. */
[[nodiscard]] bool
bool
exists(std::string const& name) const;
template <class T = std::string>
[[nodiscard]] std::optional<T>
std::optional<T>
get(std::string const& name) const
{
auto const iter = lookup_.find(name);
@@ -132,8 +132,8 @@ public:
/// Returns a value if present, else another value.
template <class T>
[[nodiscard]] T
valueOr(std::string const& name, T const& other) const
T
value_or(std::string const& name, T const& other) const
{
auto const v = get<T>(name);
return v.has_value() ? *v : other;
@@ -141,52 +141,52 @@ public:
// indicates if trailing comments were seen
// during the appending of any lines/values
[[nodiscard]] bool
hadTrailingComments() const
bool
had_trailing_comments() const
{
return hadTrailingComments_;
return had_trailing_comments_;
}
friend std::ostream&
operator<<(std::ostream&, Section const& section);
// Returns `true` if there are no key/value pairs.
[[nodiscard]] bool
bool
empty() const
{
return lookup_.empty();
}
// Returns the number of key/value pairs.
[[nodiscard]] std::size_t
std::size_t
size() const
{
return lookup_.size();
}
// For iteration of key/value pairs.
[[nodiscard]] const_iterator
const_iterator
begin() const
{
return lookup_.cbegin();
}
// For iteration of key/value pairs.
[[nodiscard]] const_iterator
const_iterator
cbegin() const
{
return lookup_.cbegin();
}
// For iteration of key/value pairs.
[[nodiscard]] const_iterator
const_iterator
end() const
{
return lookup_.cend();
}
// For iteration of key/value pairs.
[[nodiscard]] const_iterator
const_iterator
cend() const
{
return lookup_.cend();
@@ -206,7 +206,7 @@ private:
public:
/** Returns `true` if a section with the given name exists. */
[[nodiscard]] bool
bool
exists(std::string const& name) const;
/** Returns the section with the given name.
@@ -216,7 +216,7 @@ public:
Section&
section(std::string const& name);
[[nodiscard]] Section const&
Section const&
section(std::string const& name) const;
Section const&
@@ -264,7 +264,7 @@ public:
* legacy value.
* @return Contents of the legacy value.
*/
[[nodiscard]] std::string
std::string
legacy(std::string const& sectionName) const;
friend std::ostream&
@@ -272,10 +272,10 @@ public:
// indicates if trailing comments were seen
// in any loaded Sections
[[nodiscard]] bool
hadTrailingComments() const
bool
had_trailing_comments() const
{
return std::ranges::any_of(map_, [](auto s) { return s.second.hadTrailingComments(); });
return std::ranges::any_of(map_, [](auto s) { return s.second.had_trailing_comments(); });
}
protected:
@@ -294,17 +294,17 @@ template <class T>
bool
set(T& target, std::string const& name, Section const& section)
{
bool foundAndValid = false;
bool found_and_valid = false;
try
{
auto const val = section.get<T>(name);
if ((foundAndValid = val.has_value()))
if ((found_and_valid = val.has_value()))
target = *val;
}
catch (boost::bad_lexical_cast const&) // NOLINT(bugprone-empty-catch)
{
}
return foundAndValid;
return found_and_valid;
}
/** Set a value from a configuration Section
@@ -316,10 +316,10 @@ template <class T>
bool
set(T& target, T const& defaultValue, std::string const& name, Section const& section)
{
bool const foundAndValid = set<T>(target, name, section);
if (!foundAndValid)
bool const found_and_valid = set<T>(target, name, section);
if (!found_and_valid)
target = defaultValue;
return foundAndValid;
return found_and_valid;
}
/** Retrieve a key/value pair from a section.
@@ -333,7 +333,7 @@ get(Section const& section, std::string const& name, T const& defaultValue = T{}
{
try
{
return section.valueOr<T>(name, defaultValue);
return section.value_or<T>(name, defaultValue);
}
catch (boost::bad_lexical_cast const&) // NOLINT(bugprone-empty-catch)
{
@@ -358,17 +358,17 @@ get(Section const& section, std::string const& name, char const* defaultValue)
template <class T>
bool
getIfExists(Section const& section, std::string const& name, T& v)
get_if_exists(Section const& section, std::string const& name, T& v)
{
return set<T>(v, name, section);
}
template <>
inline bool
getIfExists<bool>(Section const& section, std::string const& name, bool& v)
get_if_exists<bool>(Section const& section, std::string const& name, bool& v)
{
int intVal = 0;
auto stat = getIfExists(section, name, intVal);
auto stat = get_if_exists(section, name, intVal);
if (stat)
v = bool(intVal);
return stat;

View File

@@ -101,13 +101,13 @@ public:
}
/** Returns the number of bytes in the buffer. */
[[nodiscard]] std::size_t
std::size_t
size() const noexcept
{
return size_;
}
[[nodiscard]] bool
bool
empty() const noexcept
{
return 0 == size_;
@@ -125,7 +125,7 @@ public:
to a single byte, to facilitate pointer arithmetic.
*/
/** @{ */
[[nodiscard]] std::uint8_t const*
std::uint8_t const*
data() const noexcept
{
return p_.get();
@@ -169,25 +169,25 @@ public:
return alloc(n);
}
[[nodiscard]] const_iterator
const_iterator
begin() const noexcept
{
return p_.get();
}
[[nodiscard]] const_iterator
const_iterator
cbegin() const noexcept
{
return p_.get();
}
[[nodiscard]] const_iterator
const_iterator
end() const noexcept
{
return p_.get() + size_;
}
[[nodiscard]] const_iterator
const_iterator
cend() const noexcept
{
return p_.get() + size_;

View File

@@ -19,7 +19,7 @@ public:
using Entry = std::pair<std::string, int>;
using List = std::vector<Entry>;
[[nodiscard]] List
List
getCounts(int minimumThreshold) const;
public:
@@ -38,11 +38,11 @@ public:
do
{
head = instance.head_.load();
head = instance.m_head.load();
next_ = head;
} while (instance.head_.exchange(this) != head);
} while (instance.m_head.exchange(this) != head);
++instance.count_;
++instance.m_count;
}
~Counter() noexcept = default;
@@ -59,19 +59,19 @@ public:
return --count_;
}
[[nodiscard]] int
int
getCount() const noexcept
{
return count_.load();
}
[[nodiscard]] Counter*
Counter*
getNext() const noexcept
{
return next_;
}
[[nodiscard]] std::string const&
std::string const&
getName() const noexcept
{
return name_;
@@ -88,8 +88,8 @@ private:
~CountedObjects() noexcept = default;
private:
std::atomic<int> count_;
std::atomic<Counter*> head_;
std::atomic<int> m_count;
std::atomic<Counter*> m_head;
};
//------------------------------------------------------------------------------
@@ -108,8 +108,8 @@ private:
static auto&
getCounter() noexcept
{
static CountedObjects::Counter kC{beast::typeName<Object>()};
return kC;
static CountedObjects::Counter c{beast::type_name<Object>()};
return c;
}
CountedObject() noexcept

View File

@@ -20,7 +20,7 @@ public:
/**
@param now Start time of DecayingSample.
*/
explicit DecayingSample(time_point now) : value_(value_type()), when_(now)
explicit DecayingSample(time_point now) : m_value(value_type()), m_when(now)
{
}
@@ -31,8 +31,8 @@ public:
add(value_type value, time_point now)
{
decay(now);
value_ += value;
return value_ / Window;
m_value += value;
return m_value / Window;
}
/** Retrieve the current value in normalized units.
@@ -42,7 +42,7 @@ public:
value(time_point now)
{
decay(now);
return value_ / Window;
return m_value / Window;
}
private:
@@ -50,38 +50,36 @@ private:
void
decay(time_point now)
{
if (now == when_)
if (now == m_when)
return;
if (value_ != value_type())
if (m_value != value_type())
{
std::size_t elapsed =
std::chrono::duration_cast<std::chrono::seconds>(now - when_).count();
std::chrono::duration_cast<std::chrono::seconds>(now - m_when).count();
// A span larger than four times the window decays the
// value to an insignificant amount so just reset it.
//
if (elapsed > 4 * Window)
{
value_ = value_type();
m_value = value_type();
}
else
{
for (; elapsed > 0; --elapsed)
{
value_ -= (value_ + Window - 1) / Window;
}
while ((elapsed--) != 0u)
m_value -= (m_value + Window - 1) / Window;
}
}
when_ = now;
m_when = now;
}
// Current value in exponential units
value_type value_;
value_type m_value;
// Last time the aging function was applied
time_point when_;
time_point m_when;
};
//------------------------------------------------------------------------------

View File

@@ -16,9 +16,9 @@ namespace xrpl {
*/
// Exception thrown by an invalid access to Expected.
struct BadExpectedAccess : public std::runtime_error
struct bad_expected_access : public std::runtime_error
{
BadExpectedAccess() : runtime_error("bad expected access")
bad_expected_access() : runtime_error("bad expected access")
{
}
};
@@ -26,33 +26,30 @@ struct BadExpectedAccess : public std::runtime_error
namespace detail {
// Custom policy for Expected. Always throw on an invalid access.
struct ThrowPolicy : public boost::outcome_v2::policy::base
struct throw_policy : public boost::outcome_v2::policy::base
{
template <class Impl>
static constexpr void
// NOLINTNEXTLINE(readability-identifier-naming)
wide_value_check(Impl&& self)
{
if (!base::_has_value(std::forward<Impl>(self)))
Throw<BadExpectedAccess>();
Throw<bad_expected_access>();
}
template <class Impl>
static constexpr void
// NOLINTNEXTLINE(readability-identifier-naming)
wide_error_check(Impl&& self)
{
if (!base::_has_error(std::forward<Impl>(self)))
Throw<BadExpectedAccess>();
Throw<bad_expected_access>();
}
template <class Impl>
static constexpr void
// NOLINTNEXTLINE(readability-identifier-naming)
wide_exception_check(Impl&& self)
{
if (!base::_has_exception(std::forward<Impl>(self)))
Throw<BadExpectedAccess>();
Throw<bad_expected_access>();
}
};
@@ -76,7 +73,7 @@ public:
{
}
[[nodiscard]] constexpr E const&
constexpr E const&
value() const&
{
return val_;
@@ -94,7 +91,7 @@ public:
return std::move(val_);
}
[[nodiscard]] constexpr E const&&
constexpr E const&&
value() const&&
{
return std::move(val_);
@@ -110,9 +107,9 @@ Unexpected(E (&)[N]) -> Unexpected<E const*>;
// Definition of Expected. All of the machinery comes from boost::result.
template <class T, class E>
class [[nodiscard]] Expected : private boost::outcome_v2::result<T, E, detail::ThrowPolicy>
class [[nodiscard]] Expected : private boost::outcome_v2::result<T, E, detail::throw_policy>
{
using Base = boost::outcome_v2::result<T, E, detail::ThrowPolicy>;
using Base = boost::outcome_v2::result<T, E, detail::throw_policy>;
public:
template <typename U>
@@ -128,14 +125,13 @@ public:
{
}
[[nodiscard]] constexpr bool
// NOLINTNEXTLINE(readability-identifier-naming)
constexpr bool
has_value() const
{
return Base::has_value();
}
[[nodiscard]] constexpr T const&
constexpr T const&
value() const
{
return Base::value();
@@ -147,7 +143,7 @@ public:
return Base::value();
}
[[nodiscard]] constexpr E const&
constexpr E const&
error() const
{
return Base::error();
@@ -197,9 +193,9 @@ public:
// (without a value) or the reason for the failure.
template <class E>
class [[nodiscard]]
Expected<void, E> : private boost::outcome_v2::result<void, E, detail::ThrowPolicy>
Expected<void, E> : private boost::outcome_v2::result<void, E, detail::throw_policy>
{
using Base = boost::outcome_v2::result<void, E, detail::ThrowPolicy>;
using Base = boost::outcome_v2::result<void, E, detail::throw_policy>;
public:
// The default constructor makes a successful Expected<void, E>.
@@ -214,7 +210,7 @@ public:
{
}
[[nodiscard]] constexpr E const&
constexpr E const&
error() const
{
return Base::error();

View File

@@ -159,16 +159,16 @@ public:
reset();
/** Get the raw pointer */
[[nodiscard]] T*
T*
get() const;
/** Return the strong count */
[[nodiscard]] std::size_t
useCount() const;
std::size_t
use_count() const;
template <class TT, class... Args>
friend SharedIntrusive<TT>
makeSharedIntrusive(Args&&... args);
make_SharedIntrusive(Args&&... args);
template <class TT>
friend class SharedIntrusive;
@@ -181,7 +181,7 @@ public:
private:
/** Return the raw pointer held by this object. */
[[nodiscard]] T*
T*
unsafeGetRawPtr() const;
/** Exchange the current raw pointer held by this object with the given
@@ -260,7 +260,7 @@ public:
lock() const;
/** Return true if the strong count is zero. */
[[nodiscard]] bool
bool
expired() const;
/** Set the pointer to null and decrement the weak count.
@@ -339,7 +339,7 @@ public:
don't lock the weak pointer. Use the `lock` method if that's what's
needed)
*/
[[nodiscard]] SharedIntrusive<T>
SharedIntrusive<T>
getStrong() const;
/** Return true if this is a strong pointer and the strong pointer is
@@ -357,31 +357,31 @@ public:
/** If this is a strong pointer, return the raw pointer. Otherwise
return null.
*/
[[nodiscard]] T*
T*
get() const;
/** If this is a strong pointer, return the strong count. Otherwise
* return 0
*/
[[nodiscard]] std::size_t
useCount() const;
std::size_t
use_count() const;
/** Return true if there is a non-zero strong count. */
[[nodiscard]] bool
bool
expired() const;
/** If this is a strong pointer, return the strong pointer. Otherwise
attempt to lock the weak pointer.
*/
[[nodiscard]] SharedIntrusive<T>
SharedIntrusive<T>
lock() const;
/** Return true is this represents a strong pointer. */
[[nodiscard]] bool
bool
isStrong() const;
/** Return true is this represents a weak pointer. */
[[nodiscard]] bool
bool
isWeak() const;
/** If this is a weak pointer, attempt to convert it to a strong
@@ -406,16 +406,16 @@ private:
// pointer. The low bit must be masked to zero when converting back to a
// pointer. If the low bit is '1', this is a weak pointer.
std::uintptr_t tp_{0};
static constexpr std::uintptr_t kTAG_MASK = 1;
static constexpr std::uintptr_t kPTR_MASK = ~kTAG_MASK;
static constexpr std::uintptr_t tagMask = 1;
static constexpr std::uintptr_t ptrMask = ~tagMask;
private:
/** Return the raw pointer held by this object.
*/
[[nodiscard]] T*
T*
unsafeGetRawPtr() const;
enum class RefStrength { Strong, Weak };
enum class RefStrength { strong, weak };
/** Set the raw pointer and tag bit directly.
*/
void
@@ -442,7 +442,7 @@ private:
*/
template <class TT, class... Args>
SharedIntrusive<TT>
makeSharedIntrusive(Args&&... args)
make_SharedIntrusive(Args&&... args)
{
auto p = new TT(std::forward<Args>(args)...);
@@ -469,21 +469,21 @@ using SharedWeakUnionPtr = SharedWeakUnion<T>;
template <class T, class... A>
SharedPtr<T>
makeShared(A&&... args)
make_shared(A&&... args)
{
return makeSharedIntrusive<T>(std::forward<A>(args)...);
return make_SharedIntrusive<T>(std::forward<A>(args)...);
}
template <class T, class TT>
SharedPtr<T>
staticPointerCast(TT const& v)
static_pointer_cast(TT const& v)
{
return SharedPtr<T>(StaticCastTagSharedIntrusive{}, v);
}
template <class T, class TT>
SharedPtr<T>
dynamicPointerCast(TT const& v)
dynamic_pointer_cast(TT const& v)
{
return SharedPtr<T>(DynamicCastTagSharedIntrusive{}, v);
}

View File

@@ -43,16 +43,14 @@ SharedIntrusive<T>::SharedIntrusive(SharedIntrusive<TT> const& rhs)
}
template <class T>
SharedIntrusive<T>::SharedIntrusive(SharedIntrusive&& rhs)
: ptr_{std::move(rhs).unsafeExchange(nullptr)}
SharedIntrusive<T>::SharedIntrusive(SharedIntrusive&& rhs) : ptr_{rhs.unsafeExchange(nullptr)}
{
}
template <class T>
template <class TT>
requires std::convertible_to<TT*, T*>
SharedIntrusive<T>::SharedIntrusive(SharedIntrusive<TT>&& rhs)
: ptr_{std::move(rhs).unsafeExchange(nullptr)}
SharedIntrusive<T>::SharedIntrusive(SharedIntrusive<TT>&& rhs) : ptr_{rhs.unsafeExchange(nullptr)}
{
}
template <class T>
@@ -95,7 +93,7 @@ SharedIntrusive<T>::operator=(SharedIntrusive&& rhs)
if (this == &rhs)
return *this;
unsafeReleaseAndStore(std::move(rhs).unsafeExchange(nullptr));
unsafeReleaseAndStore(rhs.unsafeExchange(nullptr));
return *this;
}
@@ -107,7 +105,7 @@ SharedIntrusive<T>::operator=(SharedIntrusive<TT>&& rhs)
{
static_assert(!std::is_same_v<T, TT>, "This overload should not be instantiated for T == TT");
unsafeReleaseAndStore(std::move(rhs).unsafeExchange(nullptr));
unsafeReleaseAndStore(rhs.unsafeExchange(nullptr));
return *this;
}
@@ -159,7 +157,7 @@ SharedIntrusive<T>::SharedIntrusive(StaticCastTagSharedIntrusive, SharedIntrusiv
template <class T>
template <class TT>
SharedIntrusive<T>::SharedIntrusive(StaticCastTagSharedIntrusive, SharedIntrusive<TT>&& rhs)
: ptr_{static_cast<T*>(std::move(rhs).unsafeExchange(nullptr))}
: ptr_{static_cast<T*>(rhs.unsafeExchange(nullptr))}
{
}
@@ -186,10 +184,8 @@ SharedIntrusive<T>::SharedIntrusive(DynamicCastTagSharedIntrusive, SharedIntrusi
{
ptr_ = dynamic_cast<T*>(toSet);
if (!ptr_)
{
// need to set the pointer back or will leak
std::move(rhs).unsafeExchange(toSet);
}
rhs.unsafeExchange(toSet);
}
}
@@ -230,10 +226,10 @@ SharedIntrusive<T>::get() const
template <class T>
std::size_t
SharedIntrusive<T>::useCount() const
SharedIntrusive<T>::use_count() const
{
if (auto p = unsafeGetRawPtr())
return p->useCount();
return p->use_count();
return 0;
}
@@ -270,12 +266,12 @@ SharedIntrusive<T>::unsafeReleaseAndStore(T* next)
auto action = prev->releaseStrongRef();
switch (action)
{
case NoOp:
case noop:
break;
case Destroy:
case destroy:
delete prev;
break;
case PartialDestroy:
case partialDestroy:
prev->partialDestructor();
partialDestructorFinished(&prev);
// prev is null and may no longer be used
@@ -349,7 +345,7 @@ template <class T>
bool
WeakIntrusive<T>::expired() const
{
return ((ptr_ == nullptr) || ptr_->expired());
return (!ptr_ || ptr_->expired());
}
template <class T>
@@ -364,16 +360,16 @@ template <class T>
void
WeakIntrusive<T>::unsafeReleaseNoStore()
{
if (ptr_ == nullptr)
if (!ptr_)
return;
using enum ReleaseWeakRefAction;
auto action = ptr_->releaseWeakRef();
switch (action)
{
case NoOp:
case noop:
break;
case Destroy:
case destroy:
delete ptr_;
break;
}
@@ -389,13 +385,9 @@ SharedWeakUnion<T>::SharedWeakUnion(SharedWeakUnion const& rhs) : tp_{rhs.tp_}
return;
if (rhs.isStrong())
{
p->addStrongRef();
}
else
{
p->addWeakRef();
}
}
template <class T>
@@ -406,7 +398,7 @@ SharedWeakUnion<T>::SharedWeakUnion(SharedIntrusive<TT> const& rhs)
auto p = rhs.unsafeGetRawPtr();
if (p)
p->addStrongRef();
unsafeSetRawPtr(p, RefStrength::Strong);
unsafeSetRawPtr(p, RefStrength::strong);
}
template <class T>
@@ -422,8 +414,8 @@ SharedWeakUnion<T>::SharedWeakUnion(SharedIntrusive<TT>&& rhs)
{
auto p = rhs.unsafeGetRawPtr();
if (p)
unsafeSetRawPtr(p, RefStrength::Strong);
std::move(rhs).unsafeSetRawPtr(nullptr);
unsafeSetRawPtr(p, RefStrength::strong);
rhs.unsafeSetRawPtr(nullptr);
}
template <class T>
@@ -439,12 +431,12 @@ SharedWeakUnion<T>::operator=(SharedWeakUnion const& rhs)
if (rhs.isStrong())
{
p->addStrongRef();
unsafeSetRawPtr(p, RefStrength::Strong);
unsafeSetRawPtr(p, RefStrength::strong);
}
else
{
p->addWeakRef();
unsafeSetRawPtr(p, RefStrength::Weak);
unsafeSetRawPtr(p, RefStrength::weak);
}
}
else
@@ -464,7 +456,7 @@ SharedWeakUnion<T>::operator=(SharedIntrusive<TT> const& rhs)
auto p = rhs.unsafeGetRawPtr();
if (p)
p->addStrongRef();
unsafeSetRawPtr(p, RefStrength::Strong);
unsafeSetRawPtr(p, RefStrength::strong);
return *this;
}
@@ -475,8 +467,8 @@ SharedWeakUnion<T>&
SharedWeakUnion<T>::operator=(SharedIntrusive<TT>&& rhs)
{
unsafeReleaseNoStore();
unsafeSetRawPtr(rhs.unsafeGetRawPtr(), RefStrength::Strong);
std::move(rhs).unsafeSetRawPtr(nullptr);
unsafeSetRawPtr(rhs.unsafeGetRawPtr(), RefStrength::strong);
rhs.unsafeSetRawPtr(nullptr);
return *this;
}
@@ -525,10 +517,10 @@ SharedWeakUnion<T>::get() const
template <class T>
std::size_t
SharedWeakUnion<T>::useCount() const
SharedWeakUnion<T>::use_count() const
{
if (auto p = get())
return p->useCount();
return p->use_count();
return 0;
}
@@ -567,14 +559,14 @@ template <class T>
bool
SharedWeakUnion<T>::isStrong() const
{
return (tp_ & kTAG_MASK) == 0u;
return !(tp_ & tagMask);
}
template <class T>
bool
SharedWeakUnion<T>::isWeak() const
{
return (tp_ & kTAG_MASK) != 0u;
return tp_ & tagMask;
}
template <class T>
@@ -589,10 +581,10 @@ SharedWeakUnion<T>::convertToStrong()
{
[[maybe_unused]] auto action = p->releaseWeakRef();
XRPL_ASSERT(
(action == ReleaseWeakRefAction::NoOp),
(action == ReleaseWeakRefAction::noop),
"xrpl::SharedWeakUnion::convertToStrong : "
"action is noop");
unsafeSetRawPtr(p, RefStrength::Strong);
unsafeSetRawPtr(p, RefStrength::strong);
return true;
}
return false;
@@ -613,9 +605,9 @@ SharedWeakUnion<T>::convertToWeak()
auto action = p->addWeakReleaseStrongRef();
switch (action)
{
case NoOp:
case noop:
break;
case Destroy:
case destroy:
// We just added a weak ref. How could we destroy?
// LCOV_EXCL_START
UNREACHABLE(
@@ -625,7 +617,7 @@ SharedWeakUnion<T>::convertToWeak()
unsafeSetRawPtr(nullptr);
return true; // Should never happen
// LCOV_EXCL_STOP
case PartialDestroy:
case partialDestroy:
// This is a weird case. We just converted the last strong
// pointer to a weak pointer.
p->partialDestructor();
@@ -633,7 +625,7 @@ SharedWeakUnion<T>::convertToWeak()
// p is null and may no longer be used
break;
}
unsafeSetRawPtr(p, RefStrength::Weak);
unsafeSetRawPtr(p, RefStrength::weak);
return true;
}
@@ -641,7 +633,7 @@ template <class T>
T*
SharedWeakUnion<T>::unsafeGetRawPtr() const
{
return reinterpret_cast<T*>(tp_ & kPTR_MASK);
return reinterpret_cast<T*>(tp_ & ptrMask);
}
template <class T>
@@ -649,8 +641,8 @@ void
SharedWeakUnion<T>::unsafeSetRawPtr(T* p, RefStrength rs)
{
tp_ = reinterpret_cast<std::uintptr_t>(p);
if (tp_ && rs == RefStrength::Weak)
tp_ |= kTAG_MASK;
if (tp_ && rs == RefStrength::weak)
tp_ |= tagMask;
}
template <class T>
@@ -674,12 +666,12 @@ SharedWeakUnion<T>::unsafeReleaseNoStore()
auto strongAction = p->releaseStrongRef();
switch (strongAction)
{
case NoOp:
case noop:
break;
case Destroy:
case destroy:
delete p;
break;
case PartialDestroy:
case partialDestroy:
p->partialDestructor();
partialDestructorFinished(&p);
// p is null and may no longer be used
@@ -692,9 +684,9 @@ SharedWeakUnion<T>::unsafeReleaseNoStore()
auto weakAction = p->releaseWeakRef();
switch (weakAction)
{
case NoOp:
case noop:
break;
case Destroy:
case destroy:
delete p;
break;
}

View File

@@ -18,7 +18,7 @@ namespace xrpl {
destroy: Run the destructor. This action will occur when either the strong
count or weak count is decremented and the other count is also zero.
*/
enum class ReleaseStrongRefAction { NoOp, PartialDestroy, Destroy };
enum class ReleaseStrongRefAction { noop, partialDestroy, destroy };
/** Action to perform when releasing a weak pointer.
@@ -28,7 +28,7 @@ enum class ReleaseStrongRefAction { NoOp, PartialDestroy, Destroy };
destroy: Run the destructor. This action will occur when either the strong
count or weak count is decremented and the other count is also zero.
*/
enum class ReleaseWeakRefAction { NoOp, Destroy };
enum class ReleaseWeakRefAction { noop, destroy };
/** Implement the strong count, weak count, and bit flags for an intrusive
pointer.
@@ -71,7 +71,7 @@ struct IntrusiveRefCounts
expired() const noexcept;
std::size_t
useCount() const noexcept;
use_count() const noexcept;
// This function MUST be called after a partial destructor finishes running.
// Calling this function may cause other threads to delete the object
@@ -98,11 +98,11 @@ private:
// enough for strong pointers and 14 bit counts are enough for weak
// pointers. Use type aliases to make it easy to switch types.
using CountType = std::uint16_t;
static constexpr size_t kSTRONG_COUNT_NUM_BITS = sizeof(CountType) * 8;
static constexpr size_t kWEAK_COUNT_NUM_BITS = kSTRONG_COUNT_NUM_BITS - 2;
static constexpr size_t StrongCountNumBits = sizeof(CountType) * 8;
static constexpr size_t WeakCountNumBits = StrongCountNumBits - 2;
using FieldType = std::uint32_t;
static constexpr size_t kFIELD_TYPE_BITS = sizeof(FieldType) * 8;
static constexpr FieldType kONE = 1;
static constexpr size_t FieldTypeBits = sizeof(FieldType) * 8;
static constexpr FieldType one = 1;
/** `refCounts` consists of four fields that are treated atomically:
@@ -137,21 +137,21 @@ private:
*/
mutable std::atomic<FieldType> refCounts_{kSTRONG_DELTA};
mutable std::atomic<FieldType> refCounts{strongDelta};
/** Amount to change the strong count when adding or releasing a reference
Note: The strong count is stored in the low `StrongCountNumBits` bits
of refCounts
*/
static constexpr FieldType kSTRONG_DELTA = 1;
static constexpr FieldType strongDelta = 1;
/** Amount to change the weak count when adding or releasing a reference
Note: The weak count is stored in the high `WeakCountNumBits` bits of
refCounts
*/
static constexpr FieldType kWEAK_DELTA = (kONE << kSTRONG_COUNT_NUM_BITS);
static constexpr FieldType weakDelta = (one << StrongCountNumBits);
/** Flag that is set when the partialDestroy function has started running
(or is about to start running).
@@ -159,34 +159,33 @@ private:
See description of the `refCounts` field for a fuller description of
this field.
*/
static constexpr FieldType kPARTIAL_DESTROY_STARTED_MASK = (kONE << (kFIELD_TYPE_BITS - 1));
static constexpr FieldType partialDestroyStartedMask = (one << (FieldTypeBits - 1));
/** Flag that is set when the partialDestroy function has finished running
See description of the `refCounts` field for a fuller description of
this field.
*/
static constexpr FieldType kPARTIAL_DESTROY_FINISHED_MASK = (kONE << (kFIELD_TYPE_BITS - 2));
static constexpr FieldType partialDestroyFinishedMask = (one << (FieldTypeBits - 2));
/** Mask that will zero out all the `count` bits and leave the tag bits
unchanged.
*/
static constexpr FieldType kTAG_MASK =
kPARTIAL_DESTROY_STARTED_MASK | kPARTIAL_DESTROY_FINISHED_MASK;
static constexpr FieldType tagMask = partialDestroyStartedMask | partialDestroyFinishedMask;
/** Mask that will zero out the `tag` bits and leave the count bits
unchanged.
*/
static constexpr FieldType kVALUE_MASK = ~kTAG_MASK;
static constexpr FieldType valueMask = ~tagMask;
/** Mask that will zero out everything except the strong count.
*/
static constexpr FieldType kSTRONG_MASK = ((kONE << kSTRONG_COUNT_NUM_BITS) - 1) & kVALUE_MASK;
static constexpr FieldType strongMask = ((one << StrongCountNumBits) - 1) & valueMask;
/** Mask that will zero out everything except the weak count.
*/
static constexpr FieldType kWEAK_MASK =
(((kONE << kWEAK_COUNT_NUM_BITS) - 1) << kSTRONG_COUNT_NUM_BITS) & kVALUE_MASK;
static constexpr FieldType weakMask =
(((one << WeakCountNumBits) - 1) << StrongCountNumBits) & valueMask;
/** Unpack the count and tag fields from the packed atomic integer form. */
struct RefCountPair
@@ -208,32 +207,32 @@ private:
RefCountPair(CountType s, CountType w) noexcept;
/** Convert back to the packed integer form. */
[[nodiscard]] FieldType
FieldType
combinedValue() const noexcept;
static constexpr CountType kMAX_STRONG_VALUE =
static_cast<CountType>((kONE << kSTRONG_COUNT_NUM_BITS) - 1);
static constexpr CountType kMAX_WEAK_VALUE =
static_cast<CountType>((kONE << kWEAK_COUNT_NUM_BITS) - 1);
static constexpr CountType maxStrongValue =
static_cast<CountType>((one << StrongCountNumBits) - 1);
static constexpr CountType maxWeakValue =
static_cast<CountType>((one << WeakCountNumBits) - 1);
/** Put an extra margin to detect when running up against limits.
This is only used in debug code, and is useful if we reduce the
number of bits in the strong and weak counts (to 16 and 14 bits).
*/
static constexpr CountType kCHECK_STRONG_MAX_VALUE = kMAX_STRONG_VALUE - 32;
static constexpr CountType kCHECK_WEAK_MAX_VALUE = kMAX_WEAK_VALUE - 32;
static constexpr CountType checkStrongMaxValue = maxStrongValue - 32;
static constexpr CountType checkWeakMaxValue = maxWeakValue - 32;
};
};
inline void
IntrusiveRefCounts::addStrongRef() const noexcept
{
refCounts_.fetch_add(kSTRONG_DELTA, std::memory_order_acq_rel);
refCounts.fetch_add(strongDelta, std::memory_order_acq_rel);
}
inline void
IntrusiveRefCounts::addWeakRef() const noexcept
{
refCounts_.fetch_add(kWEAK_DELTA, std::memory_order_acq_rel);
refCounts.fetch_add(weakDelta, std::memory_order_acq_rel);
}
inline ReleaseStrongRefAction
@@ -247,36 +246,36 @@ IntrusiveRefCounts::releaseStrongRef() const
// conditional `fetch_or`. This loop will almost always run once.
using enum ReleaseStrongRefAction;
auto prevIntVal = refCounts_.load(std::memory_order_acquire);
auto prevIntVal = refCounts.load(std::memory_order_acquire);
while (true)
{
RefCountPair const prevVal{prevIntVal};
XRPL_ASSERT(
(prevVal.strong >= kSTRONG_DELTA),
(prevVal.strong >= strongDelta),
"xrpl::IntrusiveRefCounts::releaseStrongRef : previous ref "
"higher than new");
auto nextIntVal = prevIntVal - kSTRONG_DELTA;
ReleaseStrongRefAction action = NoOp;
auto nextIntVal = prevIntVal - strongDelta;
ReleaseStrongRefAction action = noop;
if (prevVal.strong == 1)
{
if (prevVal.weak == 0)
{
action = Destroy;
action = destroy;
}
else
{
nextIntVal |= kPARTIAL_DESTROY_STARTED_MASK;
action = PartialDestroy;
nextIntVal |= partialDestroyStartedMask;
action = partialDestroy;
}
}
if (refCounts_.compare_exchange_weak(prevIntVal, nextIntVal, std::memory_order_acq_rel))
if (refCounts.compare_exchange_weak(prevIntVal, nextIntVal, std::memory_order_acq_rel))
{
// Can't be in partial destroy because only decrementing the strong
// count to zero can start a partial destroy, and that can't happen
// twice.
XRPL_ASSERT(
(action == NoOp) || !(prevIntVal & kPARTIAL_DESTROY_STARTED_MASK),
(action == noop) || !(prevIntVal & partialDestroyStartedMask),
"xrpl::IntrusiveRefCounts::releaseStrongRef : not in partial "
"destroy");
return action;
@@ -289,9 +288,9 @@ IntrusiveRefCounts::addWeakReleaseStrongRef() const
{
using enum ReleaseStrongRefAction;
static_assert(kWEAK_DELTA > kSTRONG_DELTA);
auto constexpr kDELTA = kWEAK_DELTA - kSTRONG_DELTA;
auto prevIntVal = refCounts_.load(std::memory_order_acquire);
static_assert(weakDelta > strongDelta);
auto constexpr delta = weakDelta - strongDelta;
auto prevIntVal = refCounts.load(std::memory_order_acquire);
// This loop will almost always run once. The loop is needed to atomically
// change the counts and flags (the count could be atomically changed, but
// the flags depend on the current value of the counts).
@@ -312,24 +311,24 @@ IntrusiveRefCounts::addWeakReleaseStrongRef() const
"xrpl::IntrusiveRefCounts::addWeakReleaseStrongRef : not in "
"partial destroy");
auto nextIntVal = prevIntVal + kDELTA;
ReleaseStrongRefAction action = NoOp;
auto nextIntVal = prevIntVal + delta;
ReleaseStrongRefAction action = noop;
if (prevVal.strong == 1)
{
if (prevVal.weak == 0)
{
action = NoOp;
action = noop;
}
else
{
nextIntVal |= kPARTIAL_DESTROY_STARTED_MASK;
action = PartialDestroy;
nextIntVal |= partialDestroyStartedMask;
action = partialDestroy;
}
}
if (refCounts_.compare_exchange_weak(prevIntVal, nextIntVal, std::memory_order_acq_rel))
if (refCounts.compare_exchange_weak(prevIntVal, nextIntVal, std::memory_order_acq_rel))
{
XRPL_ASSERT(
(!(prevIntVal & kPARTIAL_DESTROY_STARTED_MASK)),
(!(prevIntVal & partialDestroyStartedMask)),
"xrpl::IntrusiveRefCounts::addWeakReleaseStrongRef : not "
"started partial destroy");
return action;
@@ -340,7 +339,7 @@ IntrusiveRefCounts::addWeakReleaseStrongRef() const
inline ReleaseWeakRefAction
IntrusiveRefCounts::releaseWeakRef() const
{
auto prevIntVal = refCounts_.fetch_sub(kWEAK_DELTA, std::memory_order_acq_rel);
auto prevIntVal = refCounts.fetch_sub(weakDelta, std::memory_order_acq_rel);
RefCountPair prev = prevIntVal;
if (prev.weak == 1 && prev.strong == 0)
{
@@ -349,19 +348,19 @@ IntrusiveRefCounts::releaseWeakRef() const
// This case should only be hit if the partialDestroyStartedBit is
// set non-atomically (and even then very rarely). The code is kept
// in case we need to set the flag non-atomically for perf reasons.
refCounts_.wait(prevIntVal, std::memory_order_acquire);
prevIntVal = refCounts_.load(std::memory_order_acquire);
refCounts.wait(prevIntVal, std::memory_order_acquire);
prevIntVal = refCounts.load(std::memory_order_acquire);
prev = RefCountPair{prevIntVal};
}
if (prev.partialDestroyFinishedBit == 0u)
{
// partial destroy MUST finish before running a full destroy (when
// using weak pointers)
refCounts_.wait(prevIntVal - kWEAK_DELTA, std::memory_order_acquire);
refCounts.wait(prevIntVal - weakDelta, std::memory_order_acquire);
}
return ReleaseWeakRefAction::Destroy;
return ReleaseWeakRefAction::destroy;
}
return ReleaseWeakRefAction::NoOp;
return ReleaseWeakRefAction::noop;
}
inline bool
@@ -370,13 +369,13 @@ IntrusiveRefCounts::checkoutStrongRefFromWeak() const noexcept
auto curValue = RefCountPair{1, 1}.combinedValue();
auto desiredValue = RefCountPair{2, 1}.combinedValue();
while (!refCounts_.compare_exchange_weak(curValue, desiredValue, std::memory_order_acq_rel))
while (!refCounts.compare_exchange_weak(curValue, desiredValue, std::memory_order_acq_rel))
{
RefCountPair const prev{curValue};
if (prev.strong == 0u)
return false;
desiredValue = curValue + kSTRONG_DELTA;
desiredValue = curValue + strongDelta;
}
return true;
}
@@ -384,39 +383,38 @@ IntrusiveRefCounts::checkoutStrongRefFromWeak() const noexcept
inline bool
IntrusiveRefCounts::expired() const noexcept
{
RefCountPair const val = refCounts_.load(std::memory_order_acquire);
RefCountPair const val = refCounts.load(std::memory_order_acquire);
return val.strong == 0;
}
inline std::size_t
IntrusiveRefCounts::useCount() const noexcept
IntrusiveRefCounts::use_count() const noexcept
{
RefCountPair const val = refCounts_.load(std::memory_order_acquire);
RefCountPair const val = refCounts.load(std::memory_order_acquire);
return val.strong;
}
inline IntrusiveRefCounts::~IntrusiveRefCounts() noexcept
{
#ifndef NDEBUG
auto v = refCounts_.load(std::memory_order_acquire);
auto v = refCounts.load(std::memory_order_acquire);
XRPL_ASSERT(
(!(v & kVALUE_MASK)), "xrpl::IntrusiveRefCounts::~IntrusiveRefCounts : count must be zero");
auto t = v & kTAG_MASK;
XRPL_ASSERT(
(!t || t == kTAG_MASK), "xrpl::IntrusiveRefCounts::~IntrusiveRefCounts : valid tag");
(!(v & valueMask)), "xrpl::IntrusiveRefCounts::~IntrusiveRefCounts : count must be zero");
auto t = v & tagMask;
XRPL_ASSERT((!t || t == tagMask), "xrpl::IntrusiveRefCounts::~IntrusiveRefCounts : valid tag");
#endif
}
//------------------------------------------------------------------------------
inline IntrusiveRefCounts::RefCountPair::RefCountPair(IntrusiveRefCounts::FieldType v) noexcept
: strong{static_cast<CountType>(v & kSTRONG_MASK)}
, weak{static_cast<CountType>((v & kWEAK_MASK) >> kSTRONG_COUNT_NUM_BITS)}
, partialDestroyStartedBit{v & kPARTIAL_DESTROY_STARTED_MASK}
, partialDestroyFinishedBit{v & kPARTIAL_DESTROY_FINISHED_MASK}
: strong{static_cast<CountType>(v & strongMask)}
, weak{static_cast<CountType>((v & weakMask) >> StrongCountNumBits)}
, partialDestroyStartedBit{v & partialDestroyStartedMask}
, partialDestroyFinishedBit{v & partialDestroyFinishedMask}
{
XRPL_ASSERT(
(strong < kCHECK_STRONG_MAX_VALUE && weak < kCHECK_WEAK_MAX_VALUE),
(strong < checkStrongMaxValue && weak < checkWeakMaxValue),
"xrpl::IntrusiveRefCounts::RefCountPair(FieldType) : inputs inside "
"range");
}
@@ -427,7 +425,7 @@ inline IntrusiveRefCounts::RefCountPair::RefCountPair(
: strong{s}, weak{w}
{
XRPL_ASSERT(
(strong < kCHECK_STRONG_MAX_VALUE && weak < kCHECK_WEAK_MAX_VALUE),
(strong < checkStrongMaxValue && weak < checkWeakMaxValue),
"xrpl::IntrusiveRefCounts::RefCountPair(CountType, CountType) : "
"inputs inside range");
}
@@ -436,11 +434,11 @@ inline IntrusiveRefCounts::FieldType
IntrusiveRefCounts::RefCountPair::combinedValue() const noexcept
{
XRPL_ASSERT(
(strong < kCHECK_STRONG_MAX_VALUE && weak < kCHECK_WEAK_MAX_VALUE),
(strong < checkStrongMaxValue && weak < checkWeakMaxValue),
"xrpl::IntrusiveRefCounts::RefCountPair::combinedValue : inputs "
"inside range");
return (static_cast<IntrusiveRefCounts::FieldType>(weak)
<< IntrusiveRefCounts::kSTRONG_COUNT_NUM_BITS) |
<< IntrusiveRefCounts::StrongCountNumBits) |
static_cast<IntrusiveRefCounts::FieldType>(strong) | partialDestroyStartedBit |
partialDestroyFinishedBit;
}
@@ -451,7 +449,7 @@ partialDestructorFinished(T** o)
{
T& self = **o;
IntrusiveRefCounts::RefCountPair const p =
self.refCounts_.fetch_or(IntrusiveRefCounts::kPARTIAL_DESTROY_FINISHED_MASK);
self.refCounts.fetch_or(IntrusiveRefCounts::partialDestroyFinishedMask);
XRPL_ASSERT(
(!p.partialDestroyFinishedBit && p.partialDestroyStartedBit && !p.strong),
"xrpl::partialDestructorFinished : not a weak ref");
@@ -460,7 +458,7 @@ partialDestructorFinished(T** o)
// There was a weak count before the partial destructor ran (or we would
// have run the full destructor) and now there isn't a weak count. Some
// thread is waiting to run the destructor.
self.refCounts_.notify_one();
self.refCounts.notify_one();
}
// Set the pointer to null to emphasize that the object shouldn't be used
// after calling this function as it may be destroyed in another thread.

View File

@@ -26,17 +26,17 @@ struct LocalValues
template <class T>
struct Value : BasicValue
{
T t;
T t_;
Value() = default;
explicit Value(T t) : t(std::move(t))
explicit Value(T t) : t_(std::move(t))
{
}
void*
get() override
{
return &t;
return &t_;
}
};
@@ -55,8 +55,8 @@ template <class = void>
boost::thread_specific_ptr<detail::LocalValues>&
getLocalValues()
{
static boost::thread_specific_ptr<detail::LocalValues> kTSP(&detail::LocalValues::cleanup);
return kTSP;
static boost::thread_specific_ptr<detail::LocalValues> tsp(&detail::LocalValues::cleanup);
return tsp;
}
} // namespace detail

View File

@@ -15,17 +15,16 @@
namespace xrpl {
// DEPRECATED use beast::severities::Severity instead
// NOLINTNEXTLINE(cppcoreguidelines-use-enum-class)
enum LogSeverity {
LSInvalid = -1, // used to indicate an invalid severity
LSTrace = 0, // Very low-level progress information, details inside
lsINVALID = -1, // used to indicate an invalid severity
lsTRACE = 0, // Very low-level progress information, details inside
// an operation
LSDebug = 1, // Function-level progress information, operations
LSInfo = 2, // Server-level progress information, major operations
LSWarning = 3, // Conditions that warrant human attention, may indicate
lsDEBUG = 1, // Function-level progress information, operations
lsINFO = 2, // Server-level progress information, major operations
lsWARNING = 3, // Conditions that warrant human attention, may indicate
// a problem
LSError = 4, // A condition that indicates a problem
LSFatal = 5 // A severe condition that indicates a server problem
lsERROR = 4, // A condition that indicates a problem
lsFATAL = 5 // A severe condition that indicates a server problem
};
/** Manages partitions for logging. */
@@ -77,7 +76,7 @@ private:
@return `true` if a system file is associated and opened for
writing.
*/
[[nodiscard]] bool
bool
isOpen() const noexcept;
/** Associate a system file with the log.
@@ -130,8 +129,8 @@ private:
/** @} */
private:
std::unique_ptr<std::ofstream> stream_;
boost::filesystem::path path_;
std::unique_ptr<std::ofstream> m_stream;
boost::filesystem::path m_path;
};
std::mutex mutable mutex_;
@@ -168,7 +167,7 @@ public:
threshold(beast::severities::Severity thresh);
std::vector<std::pair<std::string, std::string>>
partitionSeverities() const;
partition_severities() const;
void
write(
@@ -208,13 +207,11 @@ public:
fromString(std::string const& s);
private:
// Need to be named before converting
// NOLINTNEXTLINE(cppcoreguidelines-use-enum-class)
enum {
// Maximum line length for log messages.
// If the message exceeds this length it will be truncated with
// ellipses.
MaximumMessageCharacters = 12 * 1024
maximumMessageCharacters = 12 * 1024
};
static void

View File

@@ -44,7 +44,7 @@ public:
return data_;
}
[[nodiscard]] ProtectedDataType const&
ProtectedDataType const&
get() const
{
return data_;
@@ -131,7 +131,7 @@ public:
* @tparam LockType The type of lock to use
* @return A lock on the mutex and a reference to the protected data
*/
template <template <typename...> typename LockType = std::scoped_lock>
template <template <typename...> typename LockType = std::lock_guard>
Lock<ProtectedDataType const, LockType, MutexType>
lock() const
{
@@ -144,7 +144,7 @@ public:
* @tparam LockType The type of lock to use
* @return A lock on the mutex and a reference to the protected data
*/
template <template <typename...> typename LockType = std::scoped_lock>
template <template <typename...> typename LockType = std::lock_guard>
Lock<ProtectedDataType, LockType, MutexType>
lock()
{

View File

@@ -70,27 +70,27 @@ isPowerOfTen(T value)
struct MantissaRange
{
using rep = std::uint64_t;
enum class MantissaScale { Small, Large };
enum mantissa_scale { small, large };
explicit constexpr MantissaRange(MantissaScale scale)
: min(getMin(scale)), log(logTen(min).value_or(-1)), scale(scale)
explicit constexpr MantissaRange(mantissa_scale scale_)
: min(getMin(scale_)), log(logTen(min).value_or(-1)), scale(scale_)
{
}
rep min;
rep max{(min * 10) - 1};
int log;
MantissaScale scale;
mantissa_scale scale;
private:
static constexpr rep
getMin(MantissaScale scale)
getMin(mantissa_scale scale_)
{
switch (scale)
switch (scale_)
{
case MantissaScale::Small:
case small:
return 1'000'000'000'000'000ULL;
case MantissaScale::Large:
case large:
return 1'000'000'000'000'000'000ULL;
default:
// Since this can never be called outside a non-constexpr
@@ -214,26 +214,26 @@ class Number
public:
// The range for the exponent when normalized
constexpr static int kMIN_EXPONENT = -32768;
constexpr static int kMAX_EXPONENT = 32768;
constexpr static int minExponent = -32768;
constexpr static int maxExponent = 32768;
constexpr static internalrep kMAX_REP = std::numeric_limits<rep>::max();
static_assert(kMAX_REP == 9'223'372'036'854'775'807);
static_assert(-kMAX_REP == std::numeric_limits<rep>::min() + 1);
constexpr static internalrep maxRep = std::numeric_limits<rep>::max();
static_assert(maxRep == 9'223'372'036'854'775'807);
static_assert(-maxRep == std::numeric_limits<rep>::min() + 1);
// May need to make unchecked private
struct Unchecked
struct unchecked
{
explicit Unchecked() = default;
explicit unchecked() = default;
};
// Like unchecked, normalized is used with the ctors that take an
// internalrep mantissa. Unlike unchecked, those ctors will normalize the
// value.
// Only unit tests are expected to use this class
struct Normalized
struct normalized
{
explicit Normalized() = default;
explicit normalized() = default;
};
explicit constexpr Number() = default;
@@ -244,17 +244,17 @@ public:
bool negative,
internalrep mantissa,
int exponent,
Unchecked) noexcept;
unchecked) noexcept;
// Assume unsigned values are... unsigned. i.e. positive
explicit constexpr Number(internalrep mantissa, int exponent, Unchecked) noexcept;
explicit constexpr Number(internalrep mantissa, int exponent, unchecked) noexcept;
// Only unit tests are expected to use this ctor
explicit Number(bool negative, internalrep mantissa, int exponent, Normalized);
explicit Number(bool negative, internalrep mantissa, int exponent, normalized);
// Assume unsigned values are... unsigned. i.e. positive
explicit Number(internalrep mantissa, int exponent, Normalized);
explicit Number(internalrep mantissa, int exponent, normalized);
[[nodiscard]] constexpr rep
constexpr rep
mantissa() const noexcept;
[[nodiscard]] constexpr int
constexpr int
exponent() const noexcept;
constexpr Number
@@ -339,7 +339,7 @@ public:
}
/** Return the sign of the amount */
[[nodiscard]] constexpr int
constexpr int
signum() const noexcept
{
if (negative_)
@@ -347,7 +347,7 @@ public:
return (mantissa_ != 0u) ? 1 : 0;
}
[[nodiscard]] Number
Number
truncate() const noexcept;
friend constexpr bool
@@ -384,44 +384,42 @@ public:
root2(Number f);
// Thread local rounding control. Default is to_nearest
enum class RoundingMode { ToNearest, TowardsZero, Downward, Upward };
static RoundingMode
enum rounding_mode { to_nearest, towards_zero, downward, upward };
static rounding_mode
getround();
static RoundingMode
setround(RoundingMode inMode);
// Returns previously set mode
static rounding_mode
setround(rounding_mode mode);
/** Returns which mantissa scale is currently in use for normalization.
*
* If you think you need to call this outside of unit tests, no you don't.
*/
static MantissaRange::MantissaScale
static MantissaRange::mantissa_scale
getMantissaScale();
/** Changes which mantissa scale is used for normalization.
*
* If you think you need to call this outside of unit tests, no you don't.
*/
static void
setMantissaScale(MantissaRange::MantissaScale scale);
setMantissaScale(MantissaRange::mantissa_scale scale);
static internalrep
minMantissa()
{
return kRANGE.get().min;
return range_.get().min;
}
static internalrep
maxMantissa()
{
return kRANGE.get().max;
return range_.get().max;
}
static int
mantissaLog()
{
return kRANGE.get().log;
return range_.get().log;
}
/// oneSmall is needed because the ranges are private
@@ -442,28 +440,28 @@ public:
normalizeToRange(T minMantissa, T maxMantissa) const;
private:
static thread_local RoundingMode mode;
static thread_local rounding_mode mode_;
// The available ranges for mantissa
constexpr static MantissaRange kSMALL_RANGE{MantissaRange::MantissaScale::Small};
static_assert(isPowerOfTen(kSMALL_RANGE.min));
static_assert(kSMALL_RANGE.min == 1'000'000'000'000'000LL);
static_assert(kSMALL_RANGE.max == 9'999'999'999'999'999LL);
static_assert(kSMALL_RANGE.log == 15);
static_assert(kSMALL_RANGE.min < kMAX_REP);
static_assert(kSMALL_RANGE.max < kMAX_REP);
constexpr static MantissaRange kLARGE_RANGE{MantissaRange::MantissaScale::Large};
static_assert(isPowerOfTen(kLARGE_RANGE.min));
static_assert(kLARGE_RANGE.min == 1'000'000'000'000'000'000ULL);
static_assert(kLARGE_RANGE.max == internalrep(9'999'999'999'999'999'999ULL));
static_assert(kLARGE_RANGE.log == 18);
static_assert(kLARGE_RANGE.min < kMAX_REP);
static_assert(kLARGE_RANGE.max > kMAX_REP);
constexpr static MantissaRange smallRange{MantissaRange::small};
static_assert(isPowerOfTen(smallRange.min));
static_assert(smallRange.min == 1'000'000'000'000'000LL);
static_assert(smallRange.max == 9'999'999'999'999'999LL);
static_assert(smallRange.log == 15);
static_assert(smallRange.min < maxRep);
static_assert(smallRange.max < maxRep);
constexpr static MantissaRange largeRange{MantissaRange::large};
static_assert(isPowerOfTen(largeRange.min));
static_assert(largeRange.min == 1'000'000'000'000'000'000ULL);
static_assert(largeRange.max == internalrep(9'999'999'999'999'999'999ULL));
static_assert(largeRange.log == 18);
static_assert(largeRange.min < maxRep);
static_assert(largeRange.max > maxRep);
// The range for the mantissa when normalized.
// Use reference_wrapper to avoid making copies, and prevent accidentally
// changing the values inside the range.
static thread_local std::reference_wrapper<MantissaRange const> kRANGE;
static thread_local std::reference_wrapper<MantissaRange const> range_;
void
normalize();
@@ -471,7 +469,7 @@ private:
/** Normalize Number components to an arbitrary range.
*
* min/maxMantissa are parameters because this function is used by both
* normalize(), which reads from kRANGE, and by normalizeToRange,
* normalize(), which reads from range_, and by normalizeToRange,
* which is public and can accept an arbitrary range from the caller.
*/
template <class T>
@@ -487,18 +485,18 @@ private:
friend void
doNormalize(
bool& negative,
T& mantissa,
int& exponent,
T& mantissa_,
int& exponent_,
MantissaRange::rep const& minMantissa,
MantissaRange::rep const& maxMantissa);
[[nodiscard]] bool
bool
isnormal() const noexcept;
// Copy the number, but modify the exponent by "exponentDelta". Because the
// mantissa doesn't change, the result will be "mostly" normalized, but the
// exponent could go out of range, so it will be checked.
[[nodiscard]] Number
Number
shiftExponent(int exponentDelta) const;
// Safely convert rep (int64) mantissa to internalrep (uint64). If the rep
@@ -511,31 +509,31 @@ private:
class Guard;
};
constexpr Number::Number(bool negative, internalrep mantissa, int exponent, Unchecked) noexcept
constexpr Number::Number(bool negative, internalrep mantissa, int exponent, unchecked) noexcept
: negative_(negative), mantissa_{mantissa}, exponent_{exponent}
{
}
constexpr Number::Number(internalrep mantissa, int exponent, Unchecked) noexcept
: Number(false, mantissa, exponent, Unchecked{})
constexpr Number::Number(internalrep mantissa, int exponent, unchecked) noexcept
: Number(false, mantissa, exponent, unchecked{})
{
}
constexpr static Number kNUM_ZERO{};
constexpr static Number numZero{};
inline Number::Number(bool negative, internalrep mantissa, int exponent, Normalized)
: Number(negative, mantissa, exponent, Unchecked{})
inline Number::Number(bool negative, internalrep mantissa, int exponent, normalized)
: Number(negative, mantissa, exponent, unchecked{})
{
normalize();
}
inline Number::Number(internalrep mantissa, int exponent, Normalized)
: Number(false, mantissa, exponent, Normalized{})
inline Number::Number(internalrep mantissa, int exponent, normalized)
: Number(false, mantissa, exponent, normalized{})
{
}
inline Number::Number(rep mantissa, int exponent)
: Number(mantissa < 0, externalToInternal(mantissa), exponent, Normalized{})
: Number(mantissa < 0, externalToInternal(mantissa), exponent, normalized{})
{
}
@@ -552,10 +550,10 @@ constexpr Number::rep
Number::mantissa() const noexcept
{
auto m = mantissa_;
if (m > kMAX_REP)
if (m > maxRep)
{
XRPL_ASSERT_PARTS(
!isnormal() || (m % 10 == 0 && m / 10 <= kMAX_REP),
!isnormal() || (m % 10 == 0 && m / 10 <= maxRep),
"xrpl::Number::mantissa",
"large normalized mantissa has no remainder");
m /= 10;
@@ -573,10 +571,10 @@ constexpr int
Number::exponent() const noexcept
{
auto e = exponent_;
if (mantissa_ > kMAX_REP)
if (mantissa_ > maxRep)
{
XRPL_ASSERT_PARTS(
!isnormal() || (mantissa_ % 10 == 0 && mantissa_ / 10 <= kMAX_REP),
!isnormal() || (mantissa_ % 10 == 0 && mantissa_ / 10 <= maxRep),
"xrpl::Number::exponent",
"large normalized mantissa has no remainder");
++e;
@@ -671,29 +669,29 @@ operator/(Number const& x, Number const& y)
inline Number
Number::min() noexcept
{
return Number{false, kRANGE.get().min, kMIN_EXPONENT, Unchecked{}};
return Number{false, range_.get().min, minExponent, unchecked{}};
}
inline Number
Number::max() noexcept
{
return Number{false, std::min(kRANGE.get().max, kMAX_REP), kMAX_EXPONENT, Unchecked{}};
return Number{false, std::min(range_.get().max, maxRep), maxExponent, unchecked{}};
}
inline Number
Number::lowest() noexcept
{
return Number{true, std::min(kRANGE.get().max, kMAX_REP), kMAX_EXPONENT, Unchecked{}};
return Number{true, std::min(range_.get().max, maxRep), maxExponent, unchecked{}};
}
inline bool
Number::isnormal() const noexcept
{
MantissaRange const& range = kRANGE;
auto const absM = mantissa_;
MantissaRange const& range = range_;
auto const abs_m = mantissa_;
return *this == Number{} ||
(range.min <= absM && absM <= range.max && (absM <= kMAX_REP || absM % 10 == 0) &&
kMIN_EXPONENT <= exponent_ && exponent_ <= kMAX_EXPONENT);
(range.min <= abs_m && abs_m <= range.max && (abs_m <= maxRep || abs_m % 10 == 0) &&
minExponent <= exponent_ && exponent_ <= maxExponent);
}
template <Integral64 T>
@@ -757,34 +755,34 @@ squelch(Number const& x, Number const& limit) noexcept
}
inline std::string
to_string(MantissaRange::MantissaScale const& scale)
to_string(MantissaRange::mantissa_scale const& scale)
{
switch (scale)
{
case MantissaRange::MantissaScale::Small:
case MantissaRange::small:
return "small";
case MantissaRange::MantissaScale::Large:
case MantissaRange::large:
return "large";
default:
throw std::runtime_error("Bad scale");
}
}
class SaveNumberRoundMode
class saveNumberRoundMode
{
Number::RoundingMode mode_;
Number::rounding_mode mode_;
public:
~SaveNumberRoundMode()
~saveNumberRoundMode()
{
Number::setround(mode_);
}
explicit SaveNumberRoundMode(Number::RoundingMode mode) noexcept : mode_{mode}
explicit saveNumberRoundMode(Number::rounding_mode mode) noexcept : mode_{mode}
{
}
SaveNumberRoundMode(SaveNumberRoundMode const&) = delete;
SaveNumberRoundMode&
operator=(SaveNumberRoundMode const&) = delete;
saveNumberRoundMode(saveNumberRoundMode const&) = delete;
saveNumberRoundMode&
operator=(saveNumberRoundMode const&) = delete;
};
// saveNumberRoundMode doesn't do quite enough for us. What we want is a
@@ -793,10 +791,10 @@ public:
// build it here.
class NumberRoundModeGuard
{
SaveNumberRoundMode saved_;
saveNumberRoundMode saved_;
public:
explicit NumberRoundModeGuard(Number::RoundingMode mode) noexcept
explicit NumberRoundModeGuard(Number::rounding_mode mode) noexcept
: saved_{Number::setround(mode)}
{
}
@@ -814,10 +812,10 @@ public:
*/
class NumberMantissaScaleGuard
{
MantissaRange::MantissaScale const saved_;
MantissaRange::mantissa_scale const saved_;
public:
explicit NumberMantissaScaleGuard(MantissaRange::MantissaScale scale) noexcept
explicit NumberMantissaScaleGuard(MantissaRange::mantissa_scale scale) noexcept
: saved_{Number::getMantissaScale()}
{
Number::setMantissaScale(scale);

View File

@@ -101,7 +101,7 @@ to_string(RangeSet<T> const& rs)
*/
template <class T>
[[nodiscard]] bool
fromString(RangeSet<T>& rs, std::string const& s)
from_string(RangeSet<T>& rs, std::string const& s)
{
std::vector<std::string> intervals;
std::vector<std::string> tokens;

View File

@@ -16,7 +16,7 @@ public:
/** Issue an asynchronous stop request. */
virtual void
stopAsync() = 0;
stop_async() = 0;
/** Issue a synchronous stop request. */
virtual void

View File

@@ -13,7 +13,7 @@ public:
explicit ResolverAsio() = default;
static std::unique_ptr<ResolverAsio>
make(boost::asio::io_context&, beast::Journal);
New(boost::asio::io_context&, beast::Journal);
};
} // namespace xrpl

View File

@@ -20,27 +20,27 @@ public:
{
}
[[nodiscard]] uint256 const&
asUint256() const
uint256 const&
as_uint256() const
{
return hash_;
}
uint256&
asUint256()
as_uint256()
{
return hash_;
}
[[nodiscard]] bool
bool
isZero() const
{
return hash_.isZero();
}
[[nodiscard]] bool
bool
isNonZero() const
{
return hash_.isNonZero();
}
[[nodiscard]] int
int
signum() const
{
return hash_.signum();
@@ -93,7 +93,7 @@ template <>
inline std::size_t
extract(SHAMapHash const& key)
{
return *reinterpret_cast<std::size_t const*>(key.asUint256().data());
return *reinterpret_cast<std::size_t const*>(key.as_uint256().data());
}
} // namespace xrpl

View File

@@ -49,7 +49,7 @@ public:
/** Return a strong pointer if this is already a strong pointer (i.e. don't
lock the weak pointer. Use the `lock` method if that's what's needed)
*/
[[nodiscard]] std::shared_ptr<T> const&
std::shared_ptr<T> const&
getStrong() const;
/** Return true if this is a strong pointer and the strong pointer is
@@ -67,30 +67,30 @@ public:
/** If this is a strong pointer, return the raw pointer. Otherwise return
null.
*/
[[nodiscard]] T*
T*
get() const;
/** If this is a strong pointer, return the strong count. Otherwise return 0
*/
[[nodiscard]] std::size_t
useCount() const;
std::size_t
use_count() const;
/** Return true if there is a non-zero strong count. */
[[nodiscard]] bool
bool
expired() const;
/** If this is a strong pointer, return the strong pointer. Otherwise
attempt to lock the weak pointer.
*/
[[nodiscard]] std::shared_ptr<T>
std::shared_ptr<T>
lock() const;
/** Return true is this represents a strong pointer. */
[[nodiscard]] bool
bool
isStrong() const;
/** Return true is this represents a weak pointer. */
[[nodiscard]] bool
bool
isWeak() const;
/** If this is a weak pointer, attempt to convert it to a strong pointer.

View File

@@ -57,10 +57,10 @@ template <class T>
std::shared_ptr<T> const&
SharedWeakCachePointer<T>::getStrong() const
{
static std::shared_ptr<T> const kEMPTY;
static std::shared_ptr<T> const empty;
if (auto p = std::get_if<std::shared_ptr<T>>(&combo_))
return *p;
return kEMPTY;
return empty;
}
template <class T>
@@ -86,7 +86,7 @@ SharedWeakCachePointer<T>::get() const
template <class T>
std::size_t
SharedWeakCachePointer<T>::useCount() const
SharedWeakCachePointer<T>::use_count() const
{
if (auto p = std::get_if<std::shared_ptr<T>>(&combo_))
return p->use_count();

View File

@@ -36,32 +36,32 @@ class SlabAllocator
struct SlabBlock
{
// A mutex to protect the freelist for this block:
std::mutex m;
std::mutex m_;
// A linked list of appropriately sized free buffers:
std::uint8_t* l = nullptr;
std::uint8_t* l_ = nullptr;
// The next memory block
SlabBlock* next;
SlabBlock* next_;
// The underlying memory block:
std::uint8_t const* const p = nullptr;
std::uint8_t const* const p_ = nullptr;
// The extent of the underlying memory block:
std::size_t const size;
std::size_t const size_;
SlabBlock(SlabBlock* next, std::uint8_t* data, std::size_t size, std::size_t item)
: next(next), p(data), size(size)
: next_(next), p_(data), size_(size)
{
// We don't need to grab the mutex here, since we're the only
// ones with access at this moment.
while (data + item <= p + size)
while (data + item <= p_ + size_)
{
// Use memcpy to avoid unaligned UB
// (will optimize to equivalent code)
std::memcpy(data, static_cast<void const*>(&l), sizeof(std::uint8_t*));
l = data;
std::memcpy(data, static_cast<void const*>(&l_), sizeof(std::uint8_t*));
l_ = data;
data += item;
}
}
@@ -81,9 +81,9 @@ class SlabAllocator
/** Determines whether the given pointer belongs to this allocator */
bool
own(std::uint8_t const* pIn) const noexcept
own(std::uint8_t const* p) const noexcept
{
return (pIn >= p) && (pIn < p + size);
return (p >= p_) && (p < p_ + size_);
}
std::uint8_t*
@@ -92,14 +92,15 @@ class SlabAllocator
std::uint8_t* ret = nullptr; // NOLINT(misc-const-correctness)
{
std::scoped_lock const lock(m);
ret = l;
std::lock_guard const l(m_);
ret = l_;
if (ret != nullptr)
{
// Use memcpy to avoid unaligned UB
// (will optimize to equivalent code)
std::memcpy(static_cast<void*>(&l), ret, sizeof(std::uint8_t*));
std::memcpy(static_cast<void*>(&l_), ret, sizeof(std::uint8_t*));
}
}
@@ -120,12 +121,12 @@ class SlabAllocator
{
XRPL_ASSERT(own(ptr), "xrpl::SlabAllocator::SlabBlock::deallocate : own input");
std::scoped_lock const lock(m);
std::lock_guard const l(m_);
// Use memcpy to avoid unaligned UB
// (will optimize to equivalent code)
std::memcpy(ptr, static_cast<void const*>(&l), sizeof(std::uint8_t*));
l = ptr;
std::memcpy(ptr, static_cast<void const*>(&l_), sizeof(std::uint8_t*));
l_ = ptr;
}
};
@@ -179,7 +180,7 @@ public:
~SlabAllocator() = default;
/** Returns the size of the memory block this allocator returns. */
[[nodiscard]] constexpr std::size_t
constexpr std::size_t
size() const noexcept
{
return itemSize_;
@@ -200,7 +201,7 @@ public:
if (auto ret = slab->allocate())
return ret;
slab = slab->next;
slab = slab->next_;
}
// No slab can satisfy our request, so we attempt to allocate a new
@@ -241,7 +242,7 @@ public:
// Link the new slab
while (!slabs_.compare_exchange_weak(
slab->next, slab, std::memory_order_release, std::memory_order_relaxed))
slab->next_, slab, std::memory_order_release, std::memory_order_relaxed))
{
; // Nothing to do
}
@@ -264,7 +265,7 @@ public:
"xrpl::SlabAllocator::SlabAllocator::deallocate : non-null "
"input");
for (auto slab = slabs_.load(); slab != nullptr; slab = slab->next)
for (auto slab = slabs_.load(); slab != nullptr; slab = slab->next_)
{
if (slab->own(ptr))
{
@@ -293,16 +294,16 @@ public:
friend class SlabAllocatorSet;
private:
std::size_t extra_;
std::size_t alloc_;
std::size_t align_;
std::size_t extra;
std::size_t alloc;
std::size_t align;
public:
constexpr SlabConfig(
std::size_t extra,
std::size_t alloc = 0,
std::size_t align = alignof(Type))
: extra_(extra), alloc_(alloc), align_(align)
std::size_t extra_,
std::size_t alloc_ = 0,
std::size_t align_ = alignof(Type))
: extra(extra_), alloc(alloc_), align(align_)
{
}
};
@@ -312,22 +313,22 @@ public:
// Ensure that the specified allocators are sorted from smallest to
// largest by size:
std::sort(std::begin(cfg), std::end(cfg), [](SlabConfig const& a, SlabConfig const& b) {
return a.extra_ < b.extra_;
return a.extra < b.extra;
});
// We should never have two slabs of the same size
if (std::adjacent_find(
std::begin(cfg), std::end(cfg), [](SlabConfig const& a, SlabConfig const& b) {
return a.extra_ == b.extra_;
return a.extra == b.extra;
}) != cfg.end())
{
throw std::runtime_error(
"SlabAllocatorSet<" + beast::typeName<Type>() + ">: duplicate slab size");
"SlabAllocatorSet<" + beast::type_name<Type>() + ">: duplicate slab size");
}
for (auto const& c : cfg)
{
auto& a = allocators_.emplace_back(c.extra_, c.alloc_, c.align_);
auto& a = allocators_.emplace_back(c.extra, c.alloc, c.align);
if (a.size() > maxSize_)
maxSize_ = a.size();

View File

@@ -74,7 +74,7 @@ public:
@note The return type is guaranteed to be a pointer
to a single byte, to facilitate pointer arithmetic.
*/
[[nodiscard]] std::uint8_t const*
std::uint8_t const*
data() const noexcept
{
return data_;
@@ -110,7 +110,7 @@ public:
/** Shrinks the slice by moving its start forward by n characters. */
void
removePrefix(std::size_t n)
remove_prefix(std::size_t n)
{
data_ += n;
size_ -= n;
@@ -118,30 +118,30 @@ public:
/** Shrinks the slice by moving its end backward by n characters. */
void
removeSuffix(std::size_t n)
remove_suffix(std::size_t n)
{
size_ -= n;
}
[[nodiscard]] const_iterator
const_iterator
begin() const noexcept
{
return data_;
}
[[nodiscard]] const_iterator
const_iterator
cbegin() const noexcept
{
return data_;
}
[[nodiscard]] const_iterator
const_iterator
end() const noexcept
{
return data_ + size_;
}
[[nodiscard]] const_iterator
const_iterator
cend() const noexcept
{
return data_ + size_;
@@ -158,7 +158,7 @@ public:
@returns The requested subslice, if the request is valid.
@throws std::out_of_range if pos > size()
*/
[[nodiscard]] Slice
Slice
substr(std::size_t pos, std::size_t count = std::numeric_limits<std::size_t>::max()) const
{
if (pos > size())

View File

@@ -30,7 +30,7 @@ template <class Iterator>
std::optional<Blob>
strUnHex(std::size_t strSize, Iterator begin, Iterator end)
{
static constexpr std::array<int, 256> const kDIGIT_LOOKUP_TABLE = []() {
static constexpr std::array<int, 256> const digitLookupTable = []() {
std::array<int, 256> t{};
for (auto& x : t)
@@ -56,7 +56,7 @@ strUnHex(std::size_t strSize, Iterator begin, Iterator end)
if (strSize & 1)
{
int c = kDIGIT_LOOKUP_TABLE[*iter++];
int c = digitLookupTable[*iter++];
if (c < 0)
return {};
@@ -66,12 +66,12 @@ strUnHex(std::size_t strSize, Iterator begin, Iterator end)
while (iter != end)
{
int const cHigh = kDIGIT_LOOKUP_TABLE[*iter++];
int const cHigh = digitLookupTable[*iter++];
if (cHigh < 0)
return {};
int const cLow = kDIGIT_LOOKUP_TABLE[*iter++];
int const cLow = digitLookupTable[*iter++];
if (cLow < 0)
return {};
@@ -94,9 +94,9 @@ strViewUnHex(std::string_view strSrc)
return strUnHex(strSrc.size(), strSrc.cbegin(), strSrc.cend());
}
struct ParsedUrl
struct parsedURL
{
explicit ParsedUrl() = default;
explicit parsedURL() = default;
std::string scheme;
std::string username;
@@ -106,7 +106,7 @@ struct ParsedUrl
std::string path;
bool
operator==(ParsedUrl const& other) const
operator==(parsedURL const& other) const
{
return scheme == other.scheme && domain == other.domain && port == other.port &&
path == other.path;
@@ -114,13 +114,13 @@ struct ParsedUrl
};
bool
parseUrl(ParsedUrl& pUrl, std::string const& strUrl);
parseUrl(parsedURL& pUrl, std::string const& strUrl);
std::string
trimWhitespace(std::string str);
trim_whitespace(std::string str);
std::optional<std::uint64_t>
toUint64(std::string const& s);
to_uint64(std::string const& s);
/** Determines if the given string looks like a TOML-file hosting domain.

View File

@@ -35,7 +35,7 @@ template <
bool IsKeyCache = false,
class SharedWeakUnionPointerType = SharedWeakCachePointer<T>,
class SharedPointerType = std::shared_ptr<T>,
class Hash = HardenedHash<>,
class Hash = hardened_hash<>,
class KeyEqual = std::equal_to<Key>,
class Mutex = std::recursive_mutex>
class TaggedCache
@@ -44,7 +44,7 @@ public:
using mutex_type = Mutex;
using key_type = Key;
using mapped_type = T;
using clock_type = beast::AbstractClock<std::chrono::steady_clock>;
using clock_type = beast::abstract_clock<std::chrono::steady_clock>;
using shared_weak_combo_pointer_type = SharedWeakUnionPointerType;
using shared_pointer_type = SharedPointerType;
@@ -55,7 +55,7 @@ public:
clock_type::duration expiration,
clock_type& clock,
beast::Journal journal,
beast::insight::Collector::ptr const& collector = beast::insight::NullCollector::make());
beast::insight::Collector::ptr const& collector = beast::insight::NullCollector::New());
public:
/** Return the clock associated with the cache. */
@@ -86,7 +86,7 @@ public:
*/
template <class KeyComparable>
bool
touchIfExists(KeyComparable const& key);
touch_if_exists(KeyComparable const& key);
using SweptPointersVector = std::vector<SharedWeakUnionPointerType>;
@@ -115,10 +115,10 @@ public:
canonicalize(key_type const& key, SharedPointerType& data, R&& replaceCallback);
bool
canonicalizeReplaceCache(key_type const& key, SharedPointerType const& data);
canonicalize_replace_cache(key_type const& key, SharedPointerType const& data);
bool
canonicalizeReplaceClient(key_type const& key, SharedPointerType& data);
canonicalize_replace_client(key_type const& key, SharedPointerType& data);
SharedPointerType
fetch(key_type const& key);
@@ -166,10 +166,10 @@ public:
private:
SharedPointerType
initialFetch(key_type const& key, std::scoped_lock<mutex_type> const& l);
initialFetch(key_type const& key, std::lock_guard<mutex_type> const& l);
void
collectMetrics();
collect_metrics();
private:
struct Stats
@@ -179,9 +179,9 @@ private:
std::string const& prefix,
Handler const& handler,
beast::insight::Collector::ptr const& collector)
: hook(collector->makeHook(handler))
, size(collector->makeGauge(prefix, "size"))
, hit_rate(collector->makeGauge(prefix, "hit_rate"))
: hook(collector->make_hook(handler))
, size(collector->make_gauge(prefix, "size"))
, hit_rate(collector->make_gauge(prefix, "hit_rate"))
{
}
@@ -199,7 +199,8 @@ private:
public:
clock_type::time_point last_access;
explicit KeyOnlyEntry(clock_type::time_point const& lastAccess) : last_access(lastAccess)
explicit KeyOnlyEntry(clock_type::time_point const& last_access_)
: last_access(last_access_)
{
}
@@ -216,24 +217,24 @@ private:
shared_weak_combo_pointer_type ptr;
clock_type::time_point last_access;
ValueEntry(clock_type::time_point const& lastAccess, shared_pointer_type const& ptr)
: ptr(ptr), last_access(lastAccess)
ValueEntry(clock_type::time_point const& last_access_, shared_pointer_type const& ptr_)
: ptr(ptr_), last_access(last_access_)
{
}
[[nodiscard]] bool
bool
isWeak() const
{
if (!ptr)
return true;
return ptr.isWeak();
}
[[nodiscard]] bool
bool
isCached() const
{
return ptr && ptr.isStrong();
}
[[nodiscard]] bool
bool
isExpired() const
{
return ptr.expired();
@@ -260,42 +261,42 @@ private:
[[nodiscard]] std::thread
sweepHelper(
clock_type::time_point const& whenExpire,
clock_type::time_point const& when_expire,
[[maybe_unused]] clock_type::time_point const& now,
typename KeyValueCacheType::map_type& partition,
SweptPointersVector& stuffToSweep,
std::atomic<int>& allRemovals,
std::scoped_lock<std::recursive_mutex> const&);
std::lock_guard<std::recursive_mutex> const&);
[[nodiscard]] std::thread
sweepHelper(
clock_type::time_point const& whenExpire,
clock_type::time_point const& when_expire,
clock_type::time_point const& now,
typename KeyOnlyCacheType::map_type& partition,
SweptPointersVector&,
std::atomic<int>& allRemovals,
std::scoped_lock<std::recursive_mutex> const&);
std::lock_guard<std::recursive_mutex> const&);
beast::Journal journal_;
clock_type& clock_;
Stats stats_;
beast::Journal m_journal;
clock_type& m_clock;
Stats m_stats;
mutex_type mutable mutex_;
mutex_type mutable m_mutex;
// Used for logging
std::string name_;
std::string m_name;
// Desired number of cache entries (0 = ignore)
int const target_size_;
int const m_target_size;
// Desired maximum cache age
clock_type::duration const target_age_;
clock_type::duration const m_target_age;
// Number of items cached
int cache_count_{0};
cache_type cache_; // Hold strong reference to recent objects
std::uint64_t hits_{0};
std::uint64_t misses_{0};
int m_cache_count{0};
cache_type m_cache; // Hold strong reference to recent objects
std::uint64_t m_hits{0};
std::uint64_t m_misses{0};
};
} // namespace xrpl

View File

@@ -30,12 +30,13 @@ inline TaggedCache<
clock_type& clock,
beast::Journal journal,
beast::insight::Collector::ptr const& collector)
: journal_(journal)
, clock_(clock)
, stats_(name, std::bind(&TaggedCache::collectMetrics, this), collector)
, name_(name)
, target_size_(size)
, target_age_(expiration)
: m_journal(journal)
, m_clock(clock)
, m_stats(name, std::bind(&TaggedCache::collect_metrics, this), collector)
, m_name(name)
, m_target_size(size)
, m_target_age(expiration)
{
}
@@ -52,7 +53,7 @@ inline auto
TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash, KeyEqual, Mutex>::
clock() -> clock_type&
{
return clock_;
return m_clock;
}
template <
@@ -68,8 +69,8 @@ inline std::size_t
TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash, KeyEqual, Mutex>::
size() const
{
std::scoped_lock const lock(mutex_);
return cache_.size();
std::lock_guard lock(m_mutex);
return m_cache.size();
}
template <
@@ -85,8 +86,8 @@ inline int
TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash, KeyEqual, Mutex>::
getCacheSize() const
{
std::scoped_lock const lock(mutex_);
return cache_count_;
std::lock_guard lock(m_mutex);
return m_cache_count;
}
template <
@@ -102,8 +103,8 @@ inline int
TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash, KeyEqual, Mutex>::
getTrackSize() const
{
std::scoped_lock const lock(mutex_);
return cache_.size();
std::lock_guard lock(m_mutex);
return m_cache.size();
}
template <
@@ -119,9 +120,9 @@ inline float
TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash, KeyEqual, Mutex>::
getHitRate()
{
std::scoped_lock const lock(mutex_);
auto const total = static_cast<float>(hits_ + misses_);
return hits_ * (100.0f / std::max(1.0f, total));
std::lock_guard lock(m_mutex);
auto const total = static_cast<float>(m_hits + m_misses);
return m_hits * (100.0f / std::max(1.0f, total));
}
template <
@@ -137,9 +138,9 @@ inline void
TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash, KeyEqual, Mutex>::
clear()
{
std::scoped_lock const lock(mutex_);
cache_.clear();
cache_count_ = 0;
std::lock_guard lock(m_mutex);
m_cache.clear();
m_cache_count = 0;
}
template <
@@ -155,11 +156,11 @@ inline void
TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash, KeyEqual, Mutex>::
reset()
{
std::scoped_lock const lock(mutex_);
cache_.clear();
cache_count_ = 0;
hits_ = 0;
misses_ = 0;
std::lock_guard lock(m_mutex);
m_cache.clear();
m_cache_count = 0;
m_hits = 0;
m_misses = 0;
}
template <
@@ -174,17 +175,17 @@ template <
template <class KeyComparable>
inline bool
TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash, KeyEqual, Mutex>::
touchIfExists(KeyComparable const& key)
touch_if_exists(KeyComparable const& key)
{
std::scoped_lock const lock(mutex_);
auto const iter(cache_.find(key));
if (iter == cache_.end())
std::lock_guard lock(m_mutex);
auto const iter(m_cache.find(key));
if (iter == m_cache.end())
{
++stats_.misses;
++m_stats.misses;
return false;
}
iter->second.touch(clock_.now());
++stats_.hits;
iter->second.touch(m_clock.now());
++m_stats.hits;
return true;
}
@@ -204,53 +205,53 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
// Keep references to all the stuff we sweep
// For performance, each worker thread should exit before the swept data
// is destroyed but still within the main cache lock.
std::vector<SweptPointersVector> allStuffToSweep(cache_.partitions());
std::vector<SweptPointersVector> allStuffToSweep(m_cache.partitions());
clock_type::time_point const now(clock_.now());
clock_type::time_point whenExpire;
clock_type::time_point const now(m_clock.now());
clock_type::time_point when_expire;
auto const start = std::chrono::steady_clock::now();
{
std::scoped_lock const lock(mutex_);
std::lock_guard lock(m_mutex);
if (target_size_ == 0 || (static_cast<int>(cache_.size()) <= target_size_))
if (m_target_size == 0 || (static_cast<int>(m_cache.size()) <= m_target_size))
{
whenExpire = now - target_age_;
when_expire = now - m_target_age;
}
else
{
whenExpire = now - (target_age_ * target_size_ / cache_.size());
when_expire = now - m_target_age * m_target_size / m_cache.size();
clock_type::duration const minimumAge(std::chrono::seconds(1));
if (whenExpire > (now - minimumAge))
whenExpire = now - minimumAge;
if (when_expire > (now - minimumAge))
when_expire = now - minimumAge;
JLOG(journal_.trace())
<< name_ << " is growing fast " << cache_.size() << " of " << target_size_
<< " aging at " << (now - whenExpire).count() << " of " << target_age_.count();
JLOG(m_journal.trace())
<< m_name << " is growing fast " << m_cache.size() << " of " << m_target_size
<< " aging at " << (now - when_expire).count() << " of " << m_target_age.count();
}
std::vector<std::thread> workers;
workers.reserve(cache_.partitions());
workers.reserve(m_cache.partitions());
std::atomic<int> allRemovals = 0;
for (std::size_t p = 0; p < cache_.partitions(); ++p)
for (std::size_t p = 0; p < m_cache.partitions(); ++p)
{
workers.push_back(sweepHelper(
whenExpire, now, cache_.map()[p], allStuffToSweep[p], allRemovals, lock));
when_expire, now, m_cache.map()[p], allStuffToSweep[p], allRemovals, lock));
}
for (std::thread& worker : workers)
worker.join();
cache_count_ -= allRemovals;
m_cache_count -= allRemovals;
}
// At this point allStuffToSweep will go out of scope outside the lock
// and decrement the reference count on each strong pointer.
JLOG(journal_.debug()) << name_ << " TaggedCache sweep lock duration "
<< std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::steady_clock::now() - start)
.count()
<< "ms";
JLOG(m_journal.debug()) << m_name << " TaggedCache sweep lock duration "
<< std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::steady_clock::now() - start)
.count()
<< "ms";
}
template <
@@ -266,12 +267,13 @@ inline bool
TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash, KeyEqual, Mutex>::
del(key_type const& key, bool valid)
{
// Remove from cache, if !valid, remove from map too. Returns true if removed from cache
std::scoped_lock const lock(mutex_);
// Remove from cache, if !valid, remove from map too. Returns true if
// removed from cache
std::lock_guard lock(m_mutex);
auto cit = cache_.find(key);
auto cit = m_cache.find(key);
if (cit == cache_.end())
if (cit == m_cache.end())
return false;
Entry& entry = cit->second;
@@ -280,13 +282,13 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
if (entry.isCached())
{
--cache_count_;
--m_cache_count;
entry.ptr.convertToWeak();
ret = true;
}
if (!valid || entry.isExpired())
cache_.erase(cit);
m_cache.erase(cit);
return ret;
}
@@ -307,22 +309,22 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
{
// Return canonical value, store if needed, refresh in cache
// Return values: true=we had the data already
std::scoped_lock const lock(mutex_);
std::lock_guard lock(m_mutex);
auto cit = cache_.find(key);
auto cit = m_cache.find(key);
if (cit == cache_.end())
if (cit == m_cache.end())
{
cache_.emplace(
m_cache.emplace(
std::piecewise_construct,
std::forward_as_tuple(key),
std::forward_as_tuple(clock_.now(), data));
++cache_count_;
std::forward_as_tuple(m_clock.now(), data));
++m_cache_count;
return false;
}
Entry& entry = cit->second;
entry.touch(clock_.now());
entry.touch(m_clock.now());
auto shouldReplace = [&] {
if constexpr (std::is_invocable_r_v<bool, R>)
@@ -366,12 +368,12 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
data = cachedData;
}
++cache_count_;
++m_cache_count;
return true;
}
entry.ptr = data;
++cache_count_;
++m_cache_count;
return false;
}
@@ -387,7 +389,7 @@ template <
class Mutex>
inline bool
TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash, KeyEqual, Mutex>::
canonicalizeReplaceCache(key_type const& key, SharedPointerType const& data)
canonicalize_replace_cache(key_type const& key, SharedPointerType const& data)
{
return canonicalize(key, const_cast<SharedPointerType&>(data), []() { return true; });
}
@@ -403,7 +405,7 @@ template <
class Mutex>
inline bool
TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash, KeyEqual, Mutex>::
canonicalizeReplaceClient(key_type const& key, SharedPointerType& data)
canonicalize_replace_client(key_type const& key, SharedPointerType& data)
{
return canonicalize(key, data, []() { return false; });
}
@@ -421,10 +423,10 @@ inline SharedPointerType
TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash, KeyEqual, Mutex>::
fetch(key_type const& key)
{
std::scoped_lock<mutex_type> const l(mutex_);
std::lock_guard<mutex_type> l(m_mutex);
auto ret = initialFetch(key, l);
if (!ret)
++misses_;
++m_misses;
return ret;
}
@@ -449,12 +451,12 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
if constexpr (std::is_same_v<std::shared_ptr<T>, SharedPointerType>)
{
auto p = std::make_shared<T>(std::cref(value));
return canonicalizeReplaceClient(key, p);
return canonicalize_replace_client(key, p);
}
if constexpr (std::is_same_v<intr_ptr::SharedPtr<T>, SharedPointerType>)
{
auto p = intr_ptr::makeShared<T>(std::cref(value));
return canonicalizeReplaceClient(key, p);
auto p = intr_ptr::make_shared<T>(std::cref(value));
return canonicalize_replace_client(key, p);
}
}
@@ -472,9 +474,9 @@ inline auto
TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash, KeyEqual, Mutex>::
insert(key_type const& key) -> std::enable_if_t<IsKeyCache, ReturnType>
{
std::scoped_lock const lock(mutex_);
clock_type::time_point const now(clock_.now());
auto [it, inserted] = cache_.emplace(
std::lock_guard lock(m_mutex);
clock_type::time_point const now(m_clock.now());
auto [it, inserted] = m_cache.emplace(
std::piecewise_construct, std::forward_as_tuple(key), std::forward_as_tuple(now));
if (!inserted)
it->second.last_access = now;
@@ -517,7 +519,7 @@ inline auto
TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash, KeyEqual, Mutex>::
peekMutex() -> mutex_type&
{
return mutex_;
return m_mutex;
}
template <
@@ -536,9 +538,9 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
std::vector<key_type> v;
{
std::scoped_lock const lock(mutex_);
v.reserve(cache_.size());
for (auto const& _ : cache_)
std::lock_guard lock(m_mutex);
v.reserve(m_cache.size());
for (auto const& _ : m_cache)
v.push_back(_.first);
}
@@ -558,11 +560,11 @@ inline double
TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash, KeyEqual, Mutex>::
rate() const
{
std::scoped_lock const lock(mutex_);
auto const tot = hits_ + misses_;
std::lock_guard lock(m_mutex);
auto const tot = m_hits + m_misses;
if (tot == 0)
return 0;
return double(hits_) / tot;
return double(m_hits) / tot;
}
template <
@@ -580,7 +582,7 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
fetch(key_type const& digest, Handler const& h)
{
{
std::scoped_lock const l(mutex_);
std::lock_guard l(m_mutex);
if (auto ret = initialFetch(digest, l))
return ret;
}
@@ -589,11 +591,11 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
if (!sle)
return {};
std::scoped_lock const l(mutex_);
++misses_;
auto const [it, inserted] = cache_.emplace(digest, Entry(clock_.now(), std::move(sle)));
std::lock_guard l(m_mutex);
++m_misses;
auto const [it, inserted] = m_cache.emplace(digest, Entry(m_clock.now(), std::move(sle)));
if (!inserted)
it->second.touch(clock_.now());
it->second.touch(m_clock.now());
return it->second.ptr.getStrong();
}
// End CachedSLEs functions.
@@ -609,29 +611,29 @@ template <
class Mutex>
inline SharedPointerType
TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash, KeyEqual, Mutex>::
initialFetch(key_type const& key, std::scoped_lock<mutex_type> const& l)
initialFetch(key_type const& key, std::lock_guard<mutex_type> const& l)
{
auto cit = cache_.find(key);
if (cit == cache_.end())
auto cit = m_cache.find(key);
if (cit == m_cache.end())
return {};
Entry& entry = cit->second;
if (entry.isCached())
{
++hits_;
entry.touch(clock_.now());
++m_hits;
entry.touch(m_clock.now());
return entry.ptr.getStrong();
}
entry.ptr = entry.lock();
if (entry.isCached())
{
// independent of cache size, so not counted as a hit
++cache_count_;
entry.touch(clock_.now());
++m_cache_count;
entry.touch(m_clock.now());
return entry.ptr.getStrong();
}
cache_.erase(cit);
m_cache.erase(cit);
return {};
}
@@ -646,19 +648,19 @@ template <
class Mutex>
inline void
TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash, KeyEqual, Mutex>::
collectMetrics()
collect_metrics()
{
stats_.size.set(getCacheSize());
m_stats.size.set(getCacheSize());
{
beast::insight::Gauge::value_type hitRate(0);
beast::insight::Gauge::value_type hit_rate(0);
{
std::scoped_lock const lock(mutex_);
auto const total(hits_ + misses_);
std::lock_guard lock(m_mutex);
auto const total(m_hits + m_misses);
if (total != 0)
hitRate = (hits_ * 100) / total;
hit_rate = (m_hits * 100) / total;
}
stats_.hit_rate.set(hitRate);
m_stats.hit_rate.set(hit_rate);
}
}
@@ -674,12 +676,12 @@ template <
inline std::thread
TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash, KeyEqual, Mutex>::
sweepHelper(
clock_type::time_point const& whenExpire,
clock_type::time_point const& when_expire,
[[maybe_unused]] clock_type::time_point const& now,
typename KeyValueCacheType::map_type& partition,
SweptPointersVector& stuffToSweep,
std::atomic<int>& allRemovals,
std::scoped_lock<std::recursive_mutex> const&)
std::lock_guard<std::recursive_mutex> const&)
{
return std::thread([&, this]() {
int cacheRemovals = 0;
@@ -706,11 +708,11 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
++cit;
}
}
else if (cit->second.last_access <= whenExpire)
else if (cit->second.last_access <= when_expire)
{
// strong, expired
++cacheRemovals;
if (cit->second.ptr.useCount() == 1)
if (cit->second.ptr.use_count() == 1)
{
stuffToSweep.emplace_back(std::move(cit->second.ptr));
++mapRemovals;
@@ -733,8 +735,8 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
if (mapRemovals || cacheRemovals)
{
JLOG(journal_.debug())
<< "TaggedCache partition sweep " << name_ << ": cache = " << partition.size()
JLOG(m_journal.debug())
<< "TaggedCache partition sweep " << m_name << ": cache = " << partition.size()
<< "-" << cacheRemovals << ", map-=" << mapRemovals;
}
@@ -754,18 +756,16 @@ template <
inline std::thread
TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash, KeyEqual, Mutex>::
sweepHelper(
clock_type::time_point const& whenExpire,
clock_type::time_point const& when_expire,
clock_type::time_point const& now,
typename KeyOnlyCacheType::map_type& partition,
SweptPointersVector&,
std::atomic<int>& allRemovals,
std::scoped_lock<std::recursive_mutex> const&)
std::lock_guard<std::recursive_mutex> const&)
{
return std::thread([&, this]() {
// NOLINTBEGIN https://github.com/XRPLF/rippled/issues/7056
int cacheRemovals = 0;
int mapRemovals = 0;
// NOLINTEND
// Keep references to all the stuff we sweep
// so that we can destroy them outside the lock.
@@ -778,7 +778,7 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
cit->second.last_access = now;
++cit;
}
else if (cit->second.last_access <= whenExpire)
else if (cit->second.last_access <= when_expire)
{
cit = partition.erase(cit);
}
@@ -789,10 +789,10 @@ TaggedCache<Key, T, IsKeyCache, SharedWeakUnionPointer, SharedPointerType, Hash,
}
}
if (mapRemovals > 0 || cacheRemovals > 0)
if (mapRemovals || cacheRemovals)
{
JLOG(journal_.debug())
<< "TaggedCache partition sweep " << name_ << ": cache = " << partition.size()
JLOG(m_journal.debug())
<< "TaggedCache partition sweep " << m_name << ": cache = " << partition.size()
<< "-" << cacheRemovals << ", map-=" << mapRemovals;
}

View File

@@ -13,31 +13,31 @@ namespace xrpl {
template <class T>
std::enable_if_t<std::is_arithmetic_v<T>, std::string>
to_string(T t) // NOLINT(readability-identifier-naming)
to_string(T t)
{
return std::to_string(t);
}
inline std::string
to_string(bool b) // NOLINT(readability-identifier-naming)
to_string(bool b)
{
return b ? "true" : "false";
}
inline std::string
to_string(char c) // NOLINT(readability-identifier-naming)
to_string(char c)
{
return std::string(1, c);
}
inline std::string
to_string(std::string s) // NOLINT(readability-identifier-naming)
to_string(std::string s)
{
return s;
}
inline std::string
to_string(char const* s) // NOLINT(readability-identifier-naming)
to_string(char const* s)
{
return s;
}

View File

@@ -28,7 +28,7 @@ namespace xrpl {
template <
class Key,
class Value,
class Hash = beast::Uhash<>,
class Hash = beast::uhash<>,
class Pred = std::equal_to<Key>,
class Allocator = std::allocator<std::pair<Key const, Value>>>
using hash_map = std::unordered_map<Key, Value, Hash, Pred, Allocator>;
@@ -36,33 +36,33 @@ using hash_map = std::unordered_map<Key, Value, Hash, Pred, Allocator>;
template <
class Key,
class Value,
class Hash = beast::Uhash<>,
class Hash = beast::uhash<>,
class Pred = std::equal_to<Key>,
class Allocator = std::allocator<std::pair<Key const, Value>>>
using hash_multimap = std::unordered_multimap<Key, Value, Hash, Pred, Allocator>;
template <
class Value,
class Hash = beast::Uhash<>,
class Hash = beast::uhash<>,
class Pred = std::equal_to<Value>,
class Allocator = std::allocator<Value>>
using hash_set = std::unordered_set<Value, Hash, Pred, Allocator>;
template <
class Value,
class Hash = beast::Uhash<>,
class Hash = beast::uhash<>,
class Pred = std::equal_to<Value>,
class Allocator = std::allocator<Value>>
using hash_multiset = std::unordered_multiset<Value, Hash, Pred, Allocator>;
// hardened_hash containers
using strong_hash = beast::Xxhasher;
using strong_hash = beast::xxhasher;
template <
class Key,
class Value,
class Hash = HardenedHash<strong_hash>,
class Hash = hardened_hash<strong_hash>,
class Pred = std::equal_to<Key>,
class Allocator = std::allocator<std::pair<Key const, Value>>>
using hardened_hash_map = std::unordered_map<Key, Value, Hash, Pred, Allocator>;
@@ -70,29 +70,29 @@ using hardened_hash_map = std::unordered_map<Key, Value, Hash, Pred, Allocator>;
template <
class Key,
class Value,
class Hash = HardenedHash<strong_hash>,
class Hash = hardened_hash<strong_hash>,
class Pred = std::equal_to<Key>,
class Allocator = std::allocator<std::pair<Key const, Value>>>
using hardened_partitioned_hash_map = PartitionedUnorderedMap<Key, Value, Hash, Pred, Allocator>;
using hardened_partitioned_hash_map = partitioned_unordered_map<Key, Value, Hash, Pred, Allocator>;
template <
class Key,
class Value,
class Hash = HardenedHash<strong_hash>,
class Hash = hardened_hash<strong_hash>,
class Pred = std::equal_to<Key>,
class Allocator = std::allocator<std::pair<Key const, Value>>>
using hardened_hash_multimap = std::unordered_multimap<Key, Value, Hash, Pred, Allocator>;
template <
class Value,
class Hash = HardenedHash<strong_hash>,
class Hash = hardened_hash<strong_hash>,
class Pred = std::equal_to<Value>,
class Allocator = std::allocator<Value>>
using hardened_hash_set = std::unordered_set<Value, Hash, Pred, Allocator>;
template <
class Value,
class Hash = HardenedHash<strong_hash>,
class Hash = hardened_hash<strong_hash>,
class Pred = std::equal_to<Value>,
class Allocator = std::allocator<Value>>
using hardened_hash_multiset = std::unordered_multiset<Value, Hash, Pred, Allocator>;

View File

@@ -21,8 +21,7 @@ public:
using period = std::ratio<1>;
using duration = std::chrono::duration<rep, period>;
using time_point = std::chrono::time_point<UptimeClock>;
static constexpr bool is_steady = // NOLINT(readability-identifier-naming)
std::chrono::system_clock::is_steady;
static constexpr bool is_steady = std::chrono::system_clock::is_steady;
explicit UptimeClock() = default;
@@ -30,19 +29,19 @@ public:
now(); // seconds since xrpld program start
private:
static std::atomic<rep> kNOW;
static std::atomic<bool> kSTOP;
static std::atomic<rep> now_;
static std::atomic<bool> stop_;
struct UpdateThread : private std::thread
struct update_thread : private std::thread
{
~UpdateThread();
UpdateThread(UpdateThread&&) = default;
~update_thread();
update_thread(update_thread&&) = default;
using std::thread::thread;
};
static UpdateThread
startClock();
static update_thread
start_clock();
};
} // namespace xrpl

View File

@@ -13,7 +13,7 @@ namespace xrpl {
// Note: This algorithm is evolved from std::set_intersection.
template <class InputIter1, class InputIter2, class Action, class Comp>
void
generalizedSetIntersection(
generalized_set_intersection(
InputIter1 first1,
InputIter1 last1,
InputIter2 first2,
@@ -53,7 +53,7 @@ generalizedSetIntersection(
// std::set_intersection.
template <class FwdIter1, class InputIter2, class Pred, class Comp>
FwdIter1
removeIfIntersectOrMatch(
remove_if_intersect_or_match(
FwdIter1 first1,
FwdIter1 last1,
InputIter2 first2,

View File

@@ -40,15 +40,15 @@
namespace xrpl {
std::string
base64Encode(std::uint8_t const* data, std::size_t len);
base64_encode(std::uint8_t const* data, std::size_t len);
inline std::string
base64Encode(std::string const& s)
base64_encode(std::string const& s)
{
return base64Encode(reinterpret_cast<std::uint8_t const*>(s.data()), s.size());
return base64_encode(reinterpret_cast<std::uint8_t const*>(s.data()), s.size());
}
std::string
base64Decode(std::string_view data);
base64_decode(std::string_view data);
} // namespace xrpl

View File

@@ -27,12 +27,12 @@ namespace xrpl {
namespace detail {
template <class Container, class = std::void_t<>>
struct IsContiguousContainer : std::false_type
struct is_contiguous_container : std::false_type
{
};
template <class Container>
struct IsContiguousContainer<
struct is_contiguous_container<
Container,
std::void_t<
decltype(std::declval<Container const>().size()),
@@ -42,7 +42,7 @@ struct IsContiguousContainer<
};
template <>
struct IsContiguousContainer<Slice> : std::true_type
struct is_contiguous_container<Slice> : std::true_type
{
};
@@ -62,18 +62,18 @@ struct IsContiguousContainer<Slice> : std::true_type
number of bits.
*/
template <std::size_t Bits, class Tag = void>
class BaseUint
class base_uint
{
static_assert((Bits % 32) == 0, "The length of a base_uint in bits must be a multiple of 32.");
static_assert(Bits >= 64, "The length of a base_uint in bits must be at least 64.");
static constexpr std::size_t kWIDTH = Bits / 32;
static constexpr std::size_t WIDTH = Bits / 32;
// This is really big-endian in byte order.
// We sometimes use std::uint32_t for speed.
std::array<std::uint32_t, kWIDTH> data_;
std::array<std::uint32_t, WIDTH> data_;
public:
//--------------------------------------------------------------------------
@@ -81,8 +81,8 @@ public:
// STL Container Interface
//
static std::size_t constexpr kBYTES = Bits / 8;
static_assert(sizeof(data_) == kBYTES, "");
static std::size_t constexpr bytes = Bits / 8;
static_assert(sizeof(data_) == bytes, "");
using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
@@ -102,7 +102,7 @@ public:
{
return reinterpret_cast<pointer>(data_.data());
}
[[nodiscard]] const_pointer
const_pointer
data() const
{
return reinterpret_cast<const_pointer>(data_.data());
@@ -116,34 +116,34 @@ public:
iterator
end()
{
return data() + kBYTES;
return data() + bytes;
}
[[nodiscard]] const_iterator
const_iterator
begin() const
{
return data();
}
[[nodiscard]] const_iterator
const_iterator
end() const
{
return data() + kBYTES;
return data() + bytes;
}
[[nodiscard]] const_iterator
const_iterator
cbegin() const
{
return data();
}
[[nodiscard]] const_iterator
const_iterator
cend() const
{
return data() + kBYTES;
return data() + bytes;
}
/** Value hashing function.
The seed prevents crafted inputs from causing degenerate parent
containers.
*/
using hasher = HardenedHash<>;
using hasher = hardened_hash<>;
//--------------------------------------------------------------------------
@@ -160,16 +160,16 @@ private:
explicit VoidHelper() = default;
};
explicit BaseUint(void const* data, VoidHelper)
explicit base_uint(void const* data, VoidHelper)
{
memcpy(data_.data(), data, kBYTES);
memcpy(data_.data(), data, bytes);
}
// Helper function to initialize a base_uint from a std::string_view.
enum class ParseResult {
Okay,
BadLength,
BadChar,
okay,
badLength,
badChar,
};
constexpr Expected<decltype(data_), ParseResult>
@@ -180,7 +180,7 @@ private:
auto hexCharToUInt = [](char c, std::uint32_t shift, std::uint32_t& accum) -> ParseResult {
std::uint32_t nibble = 0xFFu;
if (c < '0' || c > 'f')
return ParseResult::BadChar;
return ParseResult::badChar;
if (c >= 'a')
{
@@ -196,11 +196,11 @@ private:
}
if (nibble > 0xFu)
return ParseResult::BadChar;
return ParseResult::badChar;
accum |= (nibble << shift);
return ParseResult::Okay;
return ParseResult::okay;
};
decltype(data_) ret{};
@@ -211,7 +211,7 @@ private:
}
if (sv.size() != size() * 2)
return Unexpected(ParseResult::BadLength);
return Unexpected(ParseResult::badLength);
std::size_t i = 0u;
auto in = sv.begin();
@@ -221,7 +221,7 @@ private:
for (std::uint32_t const shift : {4u, 0u, 12u, 8u, 20u, 16u, 28u, 24u})
{
if (auto const result = hexCharToUInt(*in++, shift, accum);
result != ParseResult::Okay)
result != ParseResult::okay)
return Unexpected(result);
}
ret[i++] = accum;
@@ -235,7 +235,7 @@ private:
auto const result = parseFromStringView(sv);
if (!result)
{
if (result.error() == ParseResult::BadLength)
if (result.error() == ParseResult::badLength)
Throw<std::invalid_argument>("invalid length for hex string");
Throw<std::range_error>("invalid hex character");
@@ -244,15 +244,15 @@ private:
}
public:
constexpr BaseUint() : data_{}
constexpr base_uint() : data_{}
{
}
constexpr BaseUint(beast::Zero) : data_{}
constexpr base_uint(beast::Zero) : data_{}
{
}
explicit BaseUint(std::uint64_t b)
explicit base_uint(std::uint64_t b)
{
*this = b;
}
@@ -260,7 +260,7 @@ public:
// This constructor is intended to be used at compile time since it might
// throw at runtime. Consider declaring this constructor consteval once
// we get to C++23.
explicit constexpr BaseUint(std::string_view sv) noexcept(false)
explicit constexpr base_uint(std::string_view sv) noexcept(false)
: data_(parseFromStringViewThrows(sv))
{
}
@@ -268,9 +268,9 @@ public:
template <
class Container,
class = std::enable_if_t<
detail::IsContiguousContainer<Container>::value &&
detail::is_contiguous_container<Container>::value &&
std::is_trivially_copyable_v<typename Container::value_type>>>
explicit BaseUint(Container const& c)
explicit base_uint(Container const& c)
{
XRPL_ASSERT(
c.size() * sizeof(typename Container::value_type) == size(),
@@ -280,9 +280,9 @@ public:
template <class Container>
std::enable_if_t<
detail::IsContiguousContainer<Container>::value &&
detail::is_contiguous_container<Container>::value &&
std::is_trivially_copyable_v<typename Container::value_type>,
BaseUint&>
base_uint&>
operator=(Container const& c)
{
XRPL_ASSERT(
@@ -295,14 +295,14 @@ public:
/* Construct from a raw pointer.
The buffer pointed to by `data` must be at least Bits/8 bytes.
*/
static BaseUint
static base_uint
fromVoid(void const* data)
{
return BaseUint(data, VoidHelper());
return base_uint(data, VoidHelper());
}
template <class T>
static std::optional<BaseUint>
static std::optional<base_uint>
fromVoidChecked(T const& from)
{
if (from.size() != size())
@@ -310,10 +310,10 @@ public:
return fromVoid(from.data());
}
[[nodiscard]] constexpr int
constexpr int
signum() const
{
for (int i = 0; i < kWIDTH; i++)
for (int i = 0; i < WIDTH; i++)
{
if (data_[i] != 0)
return 1;
@@ -325,24 +325,24 @@ public:
bool
operator!() const
{
return *this == beast::kZERO;
return *this == beast::zero;
}
constexpr BaseUint
constexpr base_uint
operator~() const
{
BaseUint ret;
base_uint ret;
for (int i = 0; i < kWIDTH; i++)
for (int i = 0; i < WIDTH; i++)
ret.data_[i] = ~data_[i];
return ret;
}
BaseUint&
base_uint&
operator=(std::uint64_t uHost)
{
*this = beast::kZERO;
*this = beast::zero;
// NOLINTBEGIN(cppcoreguidelines-pro-type-member-init)
union
{
@@ -352,43 +352,43 @@ public:
// NOLINTEND(cppcoreguidelines-pro-type-member-init)
// Put in least significant bits.
ul = boost::endian::native_to_big(uHost);
data_[kWIDTH - 2] = u[0];
data_[kWIDTH - 1] = u[1];
data_[WIDTH - 2] = u[0];
data_[WIDTH - 1] = u[1];
return *this;
}
BaseUint&
operator^=(BaseUint const& b)
base_uint&
operator^=(base_uint const& b)
{
for (int i = 0; i < kWIDTH; i++)
for (int i = 0; i < WIDTH; i++)
data_[i] ^= b.data_[i];
return *this;
}
BaseUint&
operator&=(BaseUint const& b)
base_uint&
operator&=(base_uint const& b)
{
for (int i = 0; i < kWIDTH; i++)
for (int i = 0; i < WIDTH; i++)
data_[i] &= b.data_[i];
return *this;
}
BaseUint&
operator|=(BaseUint const& b)
base_uint&
operator|=(base_uint const& b)
{
for (int i = 0; i < kWIDTH; i++)
for (int i = 0; i < WIDTH; i++)
data_[i] |= b.data_[i];
return *this;
}
BaseUint&
base_uint&
operator++()
{
// prefix operator
for (int i = kWIDTH - 1; i >= 0; --i)
for (int i = WIDTH - 1; i >= 0; --i)
{
data_[i] = boost::endian::native_to_big(boost::endian::big_to_native(data_[i]) + 1);
if (data_[i] != 0)
@@ -398,20 +398,20 @@ public:
return *this;
}
BaseUint
base_uint
operator++(int)
{
// postfix operator
BaseUint const ret = *this;
base_uint const ret = *this;
++(*this);
return ret;
}
BaseUint&
base_uint&
operator--()
{
for (int i = kWIDTH - 1; i >= 0; --i)
for (int i = WIDTH - 1; i >= 0; --i)
{
auto prev = data_[i];
data_[i] = boost::endian::native_to_big(boost::endian::big_to_native(data_[i]) - 1);
@@ -423,36 +423,36 @@ public:
return *this;
}
BaseUint
base_uint
operator--(int)
{
// postfix operator
BaseUint const ret = *this;
base_uint const ret = *this;
--(*this);
return ret;
}
[[nodiscard]] BaseUint
base_uint
next() const
{
auto ret = *this;
return ++ret;
}
[[nodiscard]] BaseUint
base_uint
prev() const
{
auto ret = *this;
return --ret;
}
BaseUint&
operator+=(BaseUint const& b)
base_uint&
operator+=(base_uint const& b)
{
std::uint64_t carry = 0;
for (int i = kWIDTH - 1; i >= 0; i--)
for (int i = WIDTH - 1; i >= 0; i--)
{
std::uint64_t const n = carry + boost::endian::big_to_native(data_[i]) +
boost::endian::big_to_native(b.data_[i]);
@@ -466,7 +466,7 @@ public:
template <class Hasher>
friend void
hash_append(Hasher& h, BaseUint const& a) noexcept
hash_append(Hasher& h, base_uint const& a) noexcept
{
// Do not allow any endian transformations on this memory
h(a.data_.data(), sizeof(a.data_));
@@ -506,10 +506,10 @@ public:
constexpr static std::size_t
size()
{
return kBYTES;
return bytes;
}
BaseUint<Bits, Tag>&
base_uint<Bits, Tag>&
operator=(beast::Zero)
{
data_.fill(0);
@@ -517,31 +517,31 @@ public:
}
// Deprecated.
[[nodiscard]] bool
bool
isZero() const
{
return *this == beast::kZERO;
return *this == beast::zero;
}
[[nodiscard]] bool
bool
isNonZero() const
{
return *this != beast::kZERO;
return *this != beast::zero;
}
void
zero()
{
*this = beast::kZERO;
*this = beast::zero;
}
};
using uint128 = BaseUint<128>;
using uint160 = BaseUint<160>;
using uint256 = BaseUint<256>;
using uint192 = BaseUint<192>;
using uint128 = base_uint<128>;
using uint160 = base_uint<160>;
using uint256 = base_uint<256>;
using uint192 = base_uint<192>;
template <std::size_t Bits, class Tag>
[[nodiscard]] constexpr std::strong_ordering
operator<=>(BaseUint<Bits, Tag> const& lhs, BaseUint<Bits, Tag> const& rhs)
operator<=>(base_uint<Bits, Tag> const& lhs, base_uint<Bits, Tag> const& rhs)
{
// This comparison might seem wrong on a casual inspection because it
// compares data internally stored as std::uint32_t byte-by-byte. But
@@ -562,7 +562,7 @@ operator<=>(BaseUint<Bits, Tag> const& lhs, BaseUint<Bits, Tag> const& rhs)
template <std::size_t Bits, typename Tag>
[[nodiscard]] constexpr bool
operator==(BaseUint<Bits, Tag> const& lhs, BaseUint<Bits, Tag> const& rhs)
operator==(base_uint<Bits, Tag> const& lhs, base_uint<Bits, Tag> const& rhs)
{
return (lhs <=> rhs) == 0;
}
@@ -570,59 +570,59 @@ operator==(BaseUint<Bits, Tag> const& lhs, BaseUint<Bits, Tag> const& rhs)
//------------------------------------------------------------------------------
template <std::size_t Bits, class Tag>
constexpr bool
operator==(BaseUint<Bits, Tag> const& a, std::uint64_t b)
operator==(base_uint<Bits, Tag> const& a, std::uint64_t b)
{
return a == BaseUint<Bits, Tag>(b);
return a == base_uint<Bits, Tag>(b);
}
//------------------------------------------------------------------------------
template <std::size_t Bits, class Tag>
constexpr BaseUint<Bits, Tag>
operator^(BaseUint<Bits, Tag> const& a, BaseUint<Bits, Tag> const& b)
constexpr base_uint<Bits, Tag>
operator^(base_uint<Bits, Tag> const& a, base_uint<Bits, Tag> const& b)
{
return BaseUint<Bits, Tag>(a) ^= b;
return base_uint<Bits, Tag>(a) ^= b;
}
template <std::size_t Bits, class Tag>
constexpr BaseUint<Bits, Tag>
operator&(BaseUint<Bits, Tag> const& a, BaseUint<Bits, Tag> const& b)
constexpr base_uint<Bits, Tag>
operator&(base_uint<Bits, Tag> const& a, base_uint<Bits, Tag> const& b)
{
return BaseUint<Bits, Tag>(a) &= b;
return base_uint<Bits, Tag>(a) &= b;
}
template <std::size_t Bits, class Tag>
constexpr BaseUint<Bits, Tag>
operator|(BaseUint<Bits, Tag> const& a, BaseUint<Bits, Tag> const& b)
constexpr base_uint<Bits, Tag>
operator|(base_uint<Bits, Tag> const& a, base_uint<Bits, Tag> const& b)
{
return BaseUint<Bits, Tag>(a) |= b;
return base_uint<Bits, Tag>(a) |= b;
}
template <std::size_t Bits, class Tag>
constexpr BaseUint<Bits, Tag>
operator+(BaseUint<Bits, Tag> const& a, BaseUint<Bits, Tag> const& b)
constexpr base_uint<Bits, Tag>
operator+(base_uint<Bits, Tag> const& a, base_uint<Bits, Tag> const& b)
{
return BaseUint<Bits, Tag>(a) += b;
return base_uint<Bits, Tag>(a) += b;
}
//------------------------------------------------------------------------------
template <std::size_t Bits, class Tag>
inline std::string
to_string(BaseUint<Bits, Tag> const& a)
to_string(base_uint<Bits, Tag> const& a)
{
return strHex(a.cbegin(), a.cend());
}
template <std::size_t Bits, class Tag>
inline std::string
toShortString(BaseUint<Bits, Tag> const& a)
to_short_string(base_uint<Bits, Tag> const& a)
{
static_assert(BaseUint<Bits, Tag>::kBYTES > 4, "For 4 bytes or less, use a native type");
static_assert(base_uint<Bits, Tag>::bytes > 4, "For 4 bytes or less, use a native type");
return strHex(a.cbegin(), a.cbegin() + 4) + "...";
}
template <std::size_t Bits, class Tag>
inline std::ostream&
operator<<(std::ostream& out, BaseUint<Bits, Tag> const& u)
operator<<(std::ostream& out, base_uint<Bits, Tag> const& u)
{
return out << to_string(u);
}
@@ -650,9 +650,9 @@ static_assert(sizeof(uint256) == 256 / 8, "There should be no padding bytes");
namespace beast {
template <std::size_t Bits, class Tag>
struct IsUniquelyRepresented<xrpl::BaseUint<Bits, Tag>> : public std::true_type
struct is_uniquely_represented<xrpl::base_uint<Bits, Tag>> : public std::true_type
{
explicit IsUniquelyRepresented() = default;
explicit is_uniquely_represented() = default;
};
} // namespace beast

View File

@@ -30,10 +30,10 @@ using weeks = std::chrono::duration<int, std::ratio_multiply<days::period, std::
= seconds(946684800)
*/
constexpr static std::chrono::seconds kEPOCH_OFFSET =
constexpr static std::chrono::seconds epoch_offset =
date::sys_days{date::year{2000} / 1 / 1} - date::sys_days{date::year{1970} / 1 / 1};
static_assert(kEPOCH_OFFSET.count() == 946684800);
static_assert(epoch_offset.count() == 946684800);
class NetClock
{
@@ -45,7 +45,7 @@ public:
using duration = std::chrono::duration<rep, period>;
using time_point = std::chrono::time_point<NetClock>;
static bool const is_steady = false; // NOLINT(readability-identifier-naming)
static bool const is_steady = false;
};
template <class Duration>
@@ -60,42 +60,42 @@ to_string(NetClock::time_point tp)
{
// 2000-01-01 00:00:00 UTC is 946684800s from 1970-01-01 00:00:00 UTC
using namespace std::chrono;
return to_string(system_clock::time_point{tp.time_since_epoch() + kEPOCH_OFFSET});
return to_string(system_clock::time_point{tp.time_since_epoch() + epoch_offset});
}
template <class Duration>
std::string
toStringIso(date::sys_time<Duration> tp)
to_string_iso(date::sys_time<Duration> tp)
{
using namespace std::chrono;
return date::format("%FT%TZ", tp);
}
inline std::string
toStringIso(NetClock::time_point tp)
to_string_iso(NetClock::time_point tp)
{
// 2000-01-01 00:00:00 UTC is 946684800s from 1970-01-01 00:00:00 UTC
// Note, NetClock::duration is seconds, as checked by static_assert
static_assert(std::is_same_v<NetClock::duration::period, std::ratio<1>>);
return toStringIso(date::sys_time<NetClock::duration>{tp.time_since_epoch() + kEPOCH_OFFSET});
return to_string_iso(date::sys_time<NetClock::duration>{tp.time_since_epoch() + epoch_offset});
}
/** A clock for measuring elapsed time.
The epoch is unspecified.
*/
using Stopwatch = beast::AbstractClock<std::chrono::steady_clock>;
using Stopwatch = beast::abstract_clock<std::chrono::steady_clock>;
/** A manual Stopwatch for unit tests. */
using TestStopwatch = beast::ManualClock<std::chrono::steady_clock>;
using TestStopwatch = beast::manual_clock<std::chrono::steady_clock>;
/** Returns an instance of a wall clock. */
inline Stopwatch&
stopwatch()
{
using Clock = beast::BasicSecondsClock;
using Clock = beast::basic_seconds_clock;
using Facade = Clock::Clock;
return beast::getAbstractClock<Facade, Clock>();
return beast::get_abstract_clock<Facade, Clock>();
}
} // namespace xrpl

View File

@@ -17,7 +17,7 @@ namespace xrpl {
/** Generates and logs a call stack */
void
logThrow(std::string const& title);
LogThrow(std::string const& title);
/** Rethrow the exception currently being handled.
@@ -30,9 +30,9 @@ logThrow(std::string const& title);
triggering false positives, since it throws.
*/
[[noreturn]] XRPL_NO_SANITIZE_ADDRESS inline void
rethrow()
Rethrow()
{
logThrow("Re-throwing exception");
LogThrow("Re-throwing exception");
throw;
}
@@ -52,12 +52,12 @@ Throw(Args&&... args)
std::is_convertible_v<E*, std::exception*>, "Exception must derive from std::exception.");
E e(std::forward<Args>(args)...);
logThrow(std::string("Throwing exception of type " + beast::typeName<E>() + ": ") + e.what());
LogThrow(std::string("Throwing exception of type " + beast::type_name<E>() + ": ") + e.what());
throw std::move(e);
}
/** Called when faulty logic causes a broken invariant. */
[[noreturn]] void
logicError(std::string const& how) noexcept;
LogicError(std::string const& how) noexcept;
} // namespace xrpl

View File

@@ -16,24 +16,24 @@ using seed_pair = std::pair<std::uint64_t, std::uint64_t>;
template <bool = true>
seed_pair
makeSeedPair() noexcept
make_seed_pair() noexcept
{
struct StateT
struct state_t
{
std::mutex mutex;
std::random_device rng;
std::mt19937_64 gen;
std::uniform_int_distribution<std::uint64_t> dist;
StateT() : gen(rng())
state_t() : gen(rng())
{
}
// state_t(state_t const&) = delete;
// state_t& operator=(state_t const&) = delete;
};
static StateT kSTATE;
std::scoped_lock const lock(kSTATE.mutex);
return {kSTATE.dist(kSTATE.gen), kSTATE.dist(kSTATE.gen)};
static state_t state;
std::lock_guard const lock(state.mutex);
return {state.dist(state.gen), state.dist(state.gen)};
}
} // namespace detail
@@ -68,22 +68,22 @@ makeSeedPair() noexcept
see https://131002.net/siphash/#at
*/
template <class HashAlgorithm = beast::Xxhasher>
class HardenedHash
template <class HashAlgorithm = beast::xxhasher>
class hardened_hash
{
private:
detail::seed_pair seeds_{detail::makeSeedPair<>()};
detail::seed_pair m_seeds{detail::make_seed_pair<>()};
public:
using result_type = typename HashAlgorithm::result_type;
HardenedHash() = default;
hardened_hash() = default;
template <class T>
result_type
operator()(T const& t) const noexcept
{
HashAlgorithm h(seeds_.first, seeds_.second);
HashAlgorithm h(m_seeds.first, m_seeds.second);
hash_append(h, t);
return static_cast<result_type>(h);
}

View File

@@ -8,11 +8,11 @@ namespace xrpl {
/** Create a self-signed SSL context that allows anonymous Diffie Hellman. */
std::shared_ptr<boost::asio::ssl::context>
makeSslContext(std::string const& cipherList);
make_SSLContext(std::string const& cipherList);
/** Create an authenticated SSL context using the specified files. */
std::shared_ptr<boost::asio::ssl::context>
makeSslContextAuthed(
make_SSLContextAuthed(
std::string const& keyFile,
std::string const& certFile,
std::string const& chainFile,

View File

@@ -5,7 +5,7 @@
#include <optional>
namespace xrpl {
auto constexpr kMULDIV_MAX = std::numeric_limits<std::uint64_t>::max();
auto constexpr muldiv_max = std::numeric_limits<std::uint64_t>::max();
/** Return value*mul/div accurately.
Computes the result of the multiplication and division in

View File

@@ -24,7 +24,7 @@ template <>
inline std::size_t
extract(std::string const& key)
{
return ::beast::Uhash<>{}(key);
return ::beast::uhash<>{}(key);
}
template <
@@ -33,7 +33,7 @@ template <
typename Hash,
typename Pred = std::equal_to<Key>,
typename Alloc = std::allocator<std::pair<Key const, Value>>>
class PartitionedUnorderedMap
class partitioned_unordered_map
{
std::size_t partitions_;
@@ -53,46 +53,46 @@ public:
using map_type = std::unordered_map<key_type, mapped_type, hasher, key_equal, allocator_type>;
using partition_map_type = std::vector<map_type>;
struct Iterator
struct iterator
{
using iterator_category = std::forward_iterator_tag;
partition_map_type* map{nullptr};
typename partition_map_type::iterator ait{};
typename map_type::iterator mit;
partition_map_type* map_{nullptr};
typename partition_map_type::iterator ait_{};
typename map_type::iterator mit_;
Iterator() = default;
iterator() = default;
Iterator(partition_map_type* m) : map(m)
iterator(partition_map_type* map) : map_(map)
{
}
reference
operator*() const
{
return *mit;
return *mit_;
}
pointer
operator->() const
{
return &(*mit);
return &(*mit_);
}
void
inc()
{
++mit;
while (mit == ait->end())
++mit_;
while (mit_ == ait_->end())
{
++ait;
if (ait == map->end())
++ait_;
if (ait_ == map_->end())
return;
mit = ait->begin();
mit_ = ait_->begin();
}
}
// ++it
Iterator&
iterator&
operator++()
{
inc();
@@ -100,75 +100,75 @@ public:
}
// it++
Iterator
iterator
operator++(int)
{
Iterator tmp(*this);
iterator tmp(*this);
inc();
return tmp;
}
friend bool
operator==(Iterator const& lhs, Iterator const& rhs)
operator==(iterator const& lhs, iterator const& rhs)
{
return lhs.map == rhs.map && lhs.ait == rhs.ait && lhs.mit == rhs.mit;
return lhs.map_ == rhs.map_ && lhs.ait_ == rhs.ait_ && lhs.mit_ == rhs.mit_;
}
friend bool
operator!=(Iterator const& lhs, Iterator const& rhs)
operator!=(iterator const& lhs, iterator const& rhs)
{
return !(lhs == rhs);
}
};
struct ConstIterator
struct const_iterator
{
using iterator_category = std::forward_iterator_tag;
partition_map_type* map{nullptr};
typename partition_map_type::iterator ait{};
typename map_type::iterator mit;
partition_map_type* map_{nullptr};
typename partition_map_type::iterator ait_{};
typename map_type::iterator mit_;
ConstIterator() = default;
const_iterator() = default;
ConstIterator(partition_map_type* m) : map(m)
const_iterator(partition_map_type* map) : map_(map)
{
}
ConstIterator(Iterator const& orig)
const_iterator(iterator const& orig)
{
map = orig.map;
ait = orig.ait;
mit = orig.mit;
map_ = orig.map_;
ait_ = orig.ait_;
mit_ = orig.mit_;
}
const_reference
operator*() const
{
return *mit;
return *mit_;
}
const_pointer
operator->() const
{
return &(*mit);
return &(*mit_);
}
void
inc()
{
++mit;
while (mit == ait->end())
++mit_;
while (mit_ == ait_->end())
{
++ait;
if (ait == map->end())
++ait_;
if (ait_ == map_->end())
return;
mit = ait->begin();
mit_ = ait_->begin();
}
}
// ++it
ConstIterator&
const_iterator&
operator++()
{
inc();
@@ -176,22 +176,22 @@ public:
}
// it++
ConstIterator
const_iterator
operator++(int)
{
ConstIterator tmp(*this);
const_iterator tmp(*this);
inc();
return tmp;
}
friend bool
operator==(ConstIterator const& lhs, ConstIterator const& rhs)
operator==(const_iterator const& lhs, const_iterator const& rhs)
{
return lhs.map == rhs.map && lhs.ait == rhs.ait && lhs.mit == rhs.mit;
return lhs.map_ == rhs.map_ && lhs.ait_ == rhs.ait_ && lhs.mit_ == rhs.mit_;
}
friend bool
operator!=(ConstIterator const& lhs, ConstIterator const& rhs)
operator!=(const_iterator const& lhs, const_iterator const& rhs)
{
return !(lhs == rhs);
}
@@ -208,26 +208,26 @@ private:
static void
end(T& it)
{
it.ait = it.map->end();
it.mit = it.map->back().end();
it.ait_ = it.map_->end();
it.mit_ = it.map_->back().end();
}
template <class T>
static void
begin(T& it)
{
for (it.ait = it.map->begin(); it.ait != it.map->end(); ++it.ait)
for (it.ait_ = it.map_->begin(); it.ait_ != it.map_->end(); ++it.ait_)
{
if (it.ait->begin() == it.ait->end())
if (it.ait_->begin() == it.ait_->end())
continue;
it.mit = it.ait->begin();
it.mit_ = it.ait_->begin();
return;
}
end(it);
}
public:
PartitionedUnorderedMap(std::optional<std::size_t> partitions = std::nullopt)
partitioned_unordered_map(std::optional<std::size_t> partitions = std::nullopt)
{
// Set partitions to the number of hardware threads if the parameter
// is either empty or set to 0.
@@ -252,45 +252,45 @@ public:
return map_;
}
Iterator
iterator
begin()
{
Iterator it(&map_);
iterator it(&map_);
begin(it);
return it;
}
ConstIterator
const_iterator
cbegin() const
{
ConstIterator it(&map_);
const_iterator it(&map_);
begin(it);
return it;
}
ConstIterator
const_iterator
begin() const
{
return cbegin();
}
Iterator
iterator
end()
{
Iterator it(&map_);
iterator it(&map_);
end(it);
return it;
}
ConstIterator
const_iterator
cend() const
{
ConstIterator it(&map_);
const_iterator it(&map_);
end(it);
return it;
}
ConstIterator
const_iterator
end() const
{
return cend();
@@ -301,50 +301,50 @@ private:
void
find(key_type const& key, T& it) const
{
it.ait = it.map->begin() + partitioner(key);
it.mit = it.ait->find(key);
if (it.mit == it.ait->end())
it.ait_ = it.map_->begin() + partitioner(key);
it.mit_ = it.ait_->find(key);
if (it.mit_ == it.ait_->end())
end(it);
}
public:
Iterator
iterator
find(key_type const& key)
{
Iterator it(&map_);
iterator it(&map_);
find(key, it);
return it;
}
ConstIterator
const_iterator
find(key_type const& key) const
{
ConstIterator it(&map_);
const_iterator it(&map_);
find(key, it);
return it;
}
template <class T, class U>
std::pair<Iterator, bool>
std::pair<iterator, bool>
emplace(std::piecewise_construct_t const&, T&& keyTuple, U&& valueTuple)
{
auto const& key = std::get<0>(keyTuple);
Iterator it(&map_);
it.ait = it.map->begin() + partitioner(key);
auto [eit, inserted] = it.ait->emplace(
iterator it(&map_);
it.ait_ = it.map_->begin() + partitioner(key);
auto [eit, inserted] = it.ait_->emplace(
std::piecewise_construct, std::forward<T>(keyTuple), std::forward<U>(valueTuple));
it.mit = eit;
it.mit_ = eit;
return {it, inserted};
}
template <class T, class U>
std::pair<Iterator, bool>
std::pair<iterator, bool>
emplace(T&& key, U&& val)
{
Iterator it(&map_);
it.ait = it.map->begin() + partitioner(key);
auto [eit, inserted] = it.ait->emplace(std::forward<T>(key), std::forward<U>(val));
it.mit = eit;
iterator it(&map_);
it.ait_ = it.map_->begin() + partitioner(key);
auto [eit, inserted] = it.ait_->emplace(std::forward<T>(key), std::forward<U>(val));
it.mit_ = eit;
return {it, inserted};
}
@@ -355,19 +355,19 @@ public:
p.clear();
}
Iterator
erase(ConstIterator position)
iterator
erase(const_iterator position)
{
Iterator it(&map_);
it.ait = position.ait;
it.mit = position.ait->erase(position.mit);
iterator it(&map_);
it.ait_ = position.ait_;
it.mit_ = position.ait_->erase(position.mit_);
while (it.mit == it.ait->end())
while (it.mit_ == it.ait_->end())
{
++it.ait;
if (it.ait == it.map->end())
++it.ait_;
if (it.ait_ == it.map_->end())
break;
it.mit = it.ait->begin();
it.mit_ = it.ait_->begin();
}
return it;

View File

@@ -44,30 +44,30 @@ using is_engine = std::is_invocable_r<Result, Engine>;
will be randomly seeded.
*/
inline beast::xor_shift_engine&
defaultPrng()
default_prng()
{
// This is used to seed the thread-specific PRNGs on demand
static beast::xor_shift_engine kSEEDER = [] {
static beast::xor_shift_engine seeder = [] {
std::random_device rng;
std::uniform_int_distribution<std::uint64_t> distribution{1};
return beast::xor_shift_engine(distribution(rng));
}();
// This protects the seeder
static std::mutex kM;
static std::mutex m;
// The thread-specific PRNGs:
thread_local beast::xor_shift_engine kENGINE = [] {
thread_local beast::xor_shift_engine engine = [] {
std::uint64_t seed = 0;
{
std::scoped_lock const lk(kM);
std::lock_guard const lk(m);
std::uniform_int_distribution<std::uint64_t> distribution{1};
seed = distribution(kSEEDER);
seed = distribution(seeder);
}
return beast::xor_shift_engine{seed};
}();
return kENGINE;
return engine;
}
/** Return a uniformly distributed random integer.
@@ -92,7 +92,7 @@ defaultPrng()
/** @{ */
template <class Engine, class Integral>
std::enable_if_t<std::is_integral_v<Integral> && detail::is_engine<Engine>::value, Integral>
randInt(Engine& engine, Integral min, Integral max)
rand_int(Engine& engine, Integral min, Integral max)
{
XRPL_ASSERT(max > min, "xrpl::rand_int : max over min inputs");
@@ -104,37 +104,37 @@ randInt(Engine& engine, Integral min, Integral max)
template <class Integral>
std::enable_if_t<std::is_integral_v<Integral>, Integral>
randInt(Integral min, Integral max)
rand_int(Integral min, Integral max)
{
return randInt(defaultPrng(), min, max);
return rand_int(default_prng(), min, max);
}
template <class Engine, class Integral>
std::enable_if_t<std::is_integral_v<Integral> && detail::is_engine<Engine>::value, Integral>
randInt(Engine& engine, Integral max)
rand_int(Engine& engine, Integral max)
{
return randInt(engine, Integral(0), max);
return rand_int(engine, Integral(0), max);
}
template <class Integral>
std::enable_if_t<std::is_integral_v<Integral>, Integral>
randInt(Integral max)
rand_int(Integral max)
{
return randInt(defaultPrng(), max);
return rand_int(default_prng(), max);
}
template <class Integral, class Engine>
std::enable_if_t<std::is_integral_v<Integral> && detail::is_engine<Engine>::value, Integral>
randInt(Engine& engine)
rand_int(Engine& engine)
{
return randInt(engine, std::numeric_limits<Integral>::max());
return rand_int(engine, std::numeric_limits<Integral>::max());
}
template <class Integral = int>
std::enable_if_t<std::is_integral_v<Integral>, Integral>
randInt()
rand_int()
{
return randInt(defaultPrng(), std::numeric_limits<Integral>::max());
return rand_int(default_prng(), std::numeric_limits<Integral>::max());
}
/** @} */
@@ -145,17 +145,17 @@ std::enable_if_t<
(std::is_same_v<Byte, unsigned char> || std::is_same_v<Byte, std::uint8_t>) &&
detail::is_engine<Engine>::value,
Byte>
randByte(Engine& engine)
rand_byte(Engine& engine)
{
return static_cast<Byte>(randInt<Engine, std::uint32_t>(
return static_cast<Byte>(rand_int<Engine, std::uint32_t>(
engine, std::numeric_limits<Byte>::min(), std::numeric_limits<Byte>::max()));
}
template <class Byte = std::uint8_t>
std::enable_if_t<(std::is_same_v<Byte, unsigned char> || std::is_same_v<Byte, std::uint8_t>), Byte>
randByte()
rand_byte()
{
return randByte<Byte>(defaultPrng());
return rand_byte<Byte>(default_prng());
}
/** @} */
@@ -163,15 +163,15 @@ randByte()
/** @{ */
template <class Engine>
inline bool
randBool(Engine& engine)
rand_bool(Engine& engine)
{
return randInt(engine, 1) == 1;
return rand_int(engine, 1) == 1;
}
inline bool
randBool()
rand_bool()
{
return randBool(defaultPrng());
return rand_bool(default_prng());
}
/** @} */

View File

@@ -18,29 +18,29 @@ concept SafeToCast = (std::is_integral_v<Src> && std::is_integral_v<Dest>) &&
template <class Dest, class Src>
constexpr std::enable_if_t<std::is_integral_v<Dest> && std::is_integral_v<Src>, Dest>
safeCast(Src s) noexcept
safe_cast(Src s) noexcept
{
static_assert(
std::is_signed_v<Dest> || std::is_unsigned_v<Src>, "Cannot cast signed to unsigned");
constexpr unsigned kNOT_SAME = std::is_signed_v<Dest> != std::is_signed_v<Src>;
constexpr unsigned not_same = std::is_signed_v<Dest> != std::is_signed_v<Src>;
static_assert(
sizeof(Dest) >= sizeof(Src) + kNOT_SAME,
sizeof(Dest) >= sizeof(Src) + not_same,
"Destination is too small to hold all values of source");
return static_cast<Dest>(s);
}
template <class Dest, class Src>
constexpr std::enable_if_t<std::is_enum_v<Dest> && std::is_integral_v<Src>, Dest>
safeCast(Src s) noexcept
safe_cast(Src s) noexcept
{
return static_cast<Dest>(safeCast<std::underlying_type_t<Dest>>(s));
return static_cast<Dest>(safe_cast<std::underlying_type_t<Dest>>(s));
}
template <class Dest, class Src>
constexpr std::enable_if_t<std::is_integral_v<Dest> && std::is_enum_v<Src>, Dest>
safeCast(Src s) noexcept
safe_cast(Src s) noexcept
{
return safeCast<Dest>(static_cast<std::underlying_type_t<Src>>(s));
return safe_cast<Dest>(static_cast<std::underlying_type_t<Src>>(s));
}
// unsafe_cast explicitly flags a static_cast as not necessarily able to hold
@@ -49,7 +49,7 @@ safeCast(Src s) noexcept
template <class Dest, class Src>
constexpr std::enable_if_t<std::is_integral_v<Dest> && std::is_integral_v<Src>, Dest>
unsafeCast(Src s) noexcept
unsafe_cast(Src s) noexcept
{
static_assert(
!SafeToCast<Src, Dest>,
@@ -60,22 +60,22 @@ unsafeCast(Src s) noexcept
template <class Dest, class Src>
constexpr std::enable_if_t<std::is_enum_v<Dest> && std::is_integral_v<Src>, Dest>
unsafeCast(Src s) noexcept
unsafe_cast(Src s) noexcept
{
return static_cast<Dest>(unsafeCast<std::underlying_type_t<Dest>>(s));
return static_cast<Dest>(unsafe_cast<std::underlying_type_t<Dest>>(s));
}
template <class Dest, class Src>
constexpr std::enable_if_t<std::is_integral_v<Dest> && std::is_enum_v<Src>, Dest>
unsafeCast(Src s) noexcept
unsafe_cast(Src s) noexcept
{
return unsafeCast<Dest>(static_cast<std::underlying_type_t<Src>>(s));
return unsafe_cast<Dest>(static_cast<std::underlying_type_t<Src>>(s));
}
template <class Dest, class Src>
requires std::is_pointer_v<Dest>
inline Dest
safeDowncast(Src* s) noexcept
safe_downcast(Src* s) noexcept
{
#ifdef NDEBUG
return static_cast<Dest>(s); // NOLINT(cppcoreguidelines-pro-type-static-cast-downcast)
@@ -89,7 +89,7 @@ safeDowncast(Src* s) noexcept
template <class Dest, class Src>
requires std::is_lvalue_reference_v<Dest>
inline Dest
safeDowncast(Src& s) noexcept
safe_downcast(Src& s) noexcept
{
#ifndef NDEBUG
XRPL_ASSERT(

View File

@@ -22,19 +22,19 @@ namespace xrpl {
// to enforce this restriction.
template <class EF>
class ScopeExit
class scope_exit
{
EF exit_function_;
bool execute_on_destruction_{true};
public:
~ScopeExit()
~scope_exit()
{
if (execute_on_destruction_)
exit_function_();
}
ScopeExit(ScopeExit&& rhs) noexcept(
scope_exit(scope_exit&& rhs) noexcept(
std::is_nothrow_move_constructible_v<EF> || std::is_nothrow_copy_constructible_v<EF>)
: exit_function_{std::forward<EF>(rhs.exit_function_)}
, execute_on_destruction_{rhs.execute_on_destruction_}
@@ -42,14 +42,14 @@ public:
rhs.release();
}
ScopeExit&
operator=(ScopeExit&&) = delete;
scope_exit&
operator=(scope_exit&&) = delete;
template <class EFP>
explicit ScopeExit(
explicit scope_exit(
EFP&& f,
std::enable_if_t<
!std::is_same_v<std::remove_cv_t<EFP>, ScopeExit> &&
!std::is_same_v<std::remove_cv_t<EFP>, scope_exit> &&
std::is_constructible_v<EF, EFP>>* = 0) noexcept
: exit_function_{std::forward<EFP>(f)}
{
@@ -64,23 +64,23 @@ public:
};
template <class EF>
ScopeExit(EF) -> ScopeExit<EF>;
scope_exit(EF) -> scope_exit<EF>;
template <class EF>
class ScopeFail
class scope_fail
{
EF exit_function_;
bool execute_on_destruction_{true};
int uncaught_on_creation_{std::uncaught_exceptions()};
public:
~ScopeFail()
~scope_fail()
{
if (execute_on_destruction_ && std::uncaught_exceptions() > uncaught_on_creation_)
exit_function_();
}
ScopeFail(ScopeFail&& rhs) noexcept(
scope_fail(scope_fail&& rhs) noexcept(
std::is_nothrow_move_constructible_v<EF> || std::is_nothrow_copy_constructible_v<EF>)
: exit_function_{std::forward<EF>(rhs.exit_function_)}
, execute_on_destruction_{rhs.execute_on_destruction_}
@@ -89,14 +89,14 @@ public:
rhs.release();
}
ScopeFail&
operator=(ScopeFail&&) = delete;
scope_fail&
operator=(scope_fail&&) = delete;
template <class EFP>
explicit ScopeFail(
explicit scope_fail(
EFP&& f,
std::enable_if_t<
!std::is_same_v<std::remove_cv_t<EFP>, ScopeFail> &&
!std::is_same_v<std::remove_cv_t<EFP>, scope_fail> &&
std::is_constructible_v<EF, EFP>>* = 0) noexcept
: exit_function_{std::forward<EFP>(f)}
{
@@ -111,23 +111,23 @@ public:
};
template <class EF>
ScopeFail(EF) -> ScopeFail<EF>;
scope_fail(EF) -> scope_fail<EF>;
template <class EF>
class ScopeSuccess
class scope_success
{
EF exit_function_;
bool execute_on_destruction_{true};
int uncaught_on_creation_{std::uncaught_exceptions()};
public:
~ScopeSuccess() noexcept(noexcept(exit_function_()))
~scope_success() noexcept(noexcept(exit_function_()))
{
if (execute_on_destruction_ && std::uncaught_exceptions() <= uncaught_on_creation_)
exit_function_();
}
ScopeSuccess(ScopeSuccess&& rhs) noexcept(
scope_success(scope_success&& rhs) noexcept(
std::is_nothrow_move_constructible_v<EF> || std::is_nothrow_copy_constructible_v<EF>)
: exit_function_{std::forward<EF>(rhs.exit_function_)}
, execute_on_destruction_{rhs.execute_on_destruction_}
@@ -136,14 +136,14 @@ public:
rhs.release();
}
ScopeSuccess&
operator=(ScopeSuccess&&) = delete;
scope_success&
operator=(scope_success&&) = delete;
template <class EFP>
explicit ScopeSuccess(
explicit scope_success(
EFP&& f,
std::enable_if_t<
!std::is_same_v<std::remove_cv_t<EFP>, ScopeSuccess> &&
!std::is_same_v<std::remove_cv_t<EFP>, scope_success> &&
std::is_constructible_v<EF, EFP>>* =
0) noexcept(std::is_nothrow_constructible_v<EF, EFP> || std::is_nothrow_constructible_v<EF, EFP&>)
: exit_function_{std::forward<EFP>(f)}
@@ -158,7 +158,7 @@ public:
};
template <class EF>
ScopeSuccess(EF) -> ScopeSuccess<EF>;
scope_success(EF) -> scope_success<EF>;
/**
Automatically unlocks and re-locks a unique_lock object.
@@ -198,29 +198,29 @@ ScopeSuccess(EF) -> ScopeSuccess<EF>;
*/
template <class Mutex>
class ScopeUnlock
class scope_unlock
{
std::unique_lock<Mutex>* plock_;
std::unique_lock<Mutex>* plock;
public:
explicit ScopeUnlock(std::unique_lock<Mutex>& lock) noexcept(true) : plock_(&lock)
explicit scope_unlock(std::unique_lock<Mutex>& lock) noexcept(true) : plock(&lock)
{
XRPL_ASSERT(plock_->owns_lock(), "xrpl::scope_unlock::scope_unlock : mutex must be locked");
plock_->unlock();
XRPL_ASSERT(plock->owns_lock(), "xrpl::scope_unlock::scope_unlock : mutex must be locked");
plock->unlock();
}
// Immovable type
ScopeUnlock(ScopeUnlock const&) = delete;
ScopeUnlock&
operator=(ScopeUnlock const&) = delete;
scope_unlock(scope_unlock const&) = delete;
scope_unlock&
operator=(scope_unlock const&) = delete;
~ScopeUnlock() noexcept(true)
~scope_unlock() noexcept(true)
{
plock_->lock();
plock->lock();
}
};
template <class Mutex>
ScopeUnlock(std::unique_lock<Mutex>&) -> ScopeUnlock<Mutex>;
scope_unlock(std::unique_lock<Mutex>&) -> scope_unlock<Mutex>;
} // namespace xrpl

View File

@@ -26,7 +26,7 @@ namespace detail {
specific amount of time, to prevent this.
*/
inline void
spinPause() noexcept
spin_pause() noexcept
{
#ifdef __aarch64__
asm volatile("yield");
@@ -71,7 +71,7 @@ spinPause() noexcept
https://en.cppreference.com/w/cpp/named_req/Lockable
*/
template <class T>
class PackedSpinlock
class packed_spinlock
{
// clang-format off
static_assert(std::is_unsigned_v<T>);
@@ -87,9 +87,9 @@ private:
T const mask_;
public:
PackedSpinlock(PackedSpinlock const&) = delete;
PackedSpinlock&
operator=(PackedSpinlock const&) = delete;
packed_spinlock(packed_spinlock const&) = delete;
packed_spinlock&
operator=(packed_spinlock const&) = delete;
/** A single spinlock packed inside the specified atomic
@@ -99,7 +99,8 @@ public:
@note For performance reasons, you should strive to have `lock` be
on a cacheline by itself.
*/
PackedSpinlock(std::atomic<T>& lock, int index) : bits_(lock), mask_(static_cast<T>(1) << index)
packed_spinlock(std::atomic<T>& lock, int index)
: bits_(lock), mask_(static_cast<T>(1) << index)
{
XRPL_ASSERT(
index >= 0 && (mask_ != 0),
@@ -107,7 +108,7 @@ public:
}
[[nodiscard]] bool
try_lock() // NOLINT(readability-identifier-naming)
try_lock()
{
return (bits_.fetch_or(mask_, std::memory_order_acquire) & mask_) == 0;
}
@@ -122,7 +123,7 @@ public:
// of contention by avoiding writes that would definitely not
// result in the lock being acquired.
while ((bits_.load(std::memory_order_relaxed) & mask_) != 0)
detail::spinPause();
detail::spin_pause();
}
}
@@ -146,7 +147,7 @@ public:
https://en.cppreference.com/w/cpp/named_req/Lockable
*/
template <class T>
class Spinlock
class spinlock
{
static_assert(std::is_unsigned_v<T>);
static_assert(std::atomic<T>::is_always_lock_free);
@@ -155,9 +156,9 @@ private:
std::atomic<T>& lock_;
public:
Spinlock(Spinlock const&) = delete;
Spinlock&
operator=(Spinlock const&) = delete;
spinlock(spinlock const&) = delete;
spinlock&
operator=(spinlock const&) = delete;
/** Grabs the
@@ -166,12 +167,12 @@ public:
@note For performance reasons, you should strive to have `lock` be
on a cacheline by itself.
*/
Spinlock(std::atomic<T>& lock) : lock_(lock)
spinlock(std::atomic<T>& lock) : lock_(lock)
{
}
[[nodiscard]] bool
try_lock() // NOLINT(readability-identifier-naming)
try_lock()
{
T expected = 0;
@@ -192,7 +193,7 @@ public:
// of contention by avoiding writes that would definitely not
// result in the lock being acquired.
while (lock_.load(std::memory_order_relaxed) != 0)
detail::spinPause();
detail::spin_pause();
}
}

View File

@@ -23,171 +23,171 @@ namespace xrpl {
allowed arithmetic operations.
*/
template <class Int, class Tag>
class TaggedInteger : boost::totally_ordered<
TaggedInteger<Int, Tag>,
boost::integer_arithmetic<
TaggedInteger<Int, Tag>,
boost::bitwise<
TaggedInteger<Int, Tag>,
boost::unit_steppable<
TaggedInteger<Int, Tag>,
boost::shiftable<TaggedInteger<Int, Tag>>>>>>
class tagged_integer : boost::totally_ordered<
tagged_integer<Int, Tag>,
boost::integer_arithmetic<
tagged_integer<Int, Tag>,
boost::bitwise<
tagged_integer<Int, Tag>,
boost::unit_steppable<
tagged_integer<Int, Tag>,
boost::shiftable<tagged_integer<Int, Tag>>>>>>
{
private:
Int value_;
Int m_value;
public:
using value_type = Int;
using tag_type = Tag;
TaggedInteger() = default;
tagged_integer() = default;
template <
class OtherInt,
class = std::enable_if_t<std::is_integral_v<OtherInt> && sizeof(OtherInt) <= sizeof(Int)>>
explicit constexpr TaggedInteger(OtherInt value) noexcept : value_(value)
explicit constexpr tagged_integer(OtherInt value) noexcept : m_value(value)
{
static_assert(sizeof(TaggedInteger) == sizeof(Int), "tagged_integer is adding padding");
static_assert(sizeof(tagged_integer) == sizeof(Int), "tagged_integer is adding padding");
}
bool
operator<(TaggedInteger const& rhs) const noexcept
operator<(tagged_integer const& rhs) const noexcept
{
return value_ < rhs.value_;
return m_value < rhs.m_value;
}
bool
operator==(TaggedInteger const& rhs) const noexcept
operator==(tagged_integer const& rhs) const noexcept
{
return value_ == rhs.value_;
return m_value == rhs.m_value;
}
TaggedInteger&
operator+=(TaggedInteger const& rhs) noexcept
tagged_integer&
operator+=(tagged_integer const& rhs) noexcept
{
value_ += rhs.value_;
m_value += rhs.m_value;
return *this;
}
TaggedInteger&
operator-=(TaggedInteger const& rhs) noexcept
tagged_integer&
operator-=(tagged_integer const& rhs) noexcept
{
value_ -= rhs.value_;
m_value -= rhs.m_value;
return *this;
}
TaggedInteger&
operator*=(TaggedInteger const& rhs) noexcept
tagged_integer&
operator*=(tagged_integer const& rhs) noexcept
{
value_ *= rhs.value_;
m_value *= rhs.m_value;
return *this;
}
TaggedInteger&
operator/=(TaggedInteger const& rhs) noexcept
tagged_integer&
operator/=(tagged_integer const& rhs) noexcept
{
value_ /= rhs.value_;
m_value /= rhs.m_value;
return *this;
}
TaggedInteger&
operator%=(TaggedInteger const& rhs) noexcept
tagged_integer&
operator%=(tagged_integer const& rhs) noexcept
{
value_ %= rhs.value_;
m_value %= rhs.m_value;
return *this;
}
TaggedInteger&
operator|=(TaggedInteger const& rhs) noexcept
tagged_integer&
operator|=(tagged_integer const& rhs) noexcept
{
value_ |= rhs.value_;
m_value |= rhs.m_value;
return *this;
}
TaggedInteger&
operator&=(TaggedInteger const& rhs) noexcept
tagged_integer&
operator&=(tagged_integer const& rhs) noexcept
{
value_ &= rhs.value_;
m_value &= rhs.m_value;
return *this;
}
TaggedInteger&
operator^=(TaggedInteger const& rhs) noexcept
tagged_integer&
operator^=(tagged_integer const& rhs) noexcept
{
value_ ^= rhs.value_;
m_value ^= rhs.m_value;
return *this;
}
TaggedInteger&
operator<<=(TaggedInteger const& rhs) noexcept
tagged_integer&
operator<<=(tagged_integer const& rhs) noexcept
{
value_ <<= rhs.value_;
m_value <<= rhs.m_value;
return *this;
}
TaggedInteger&
operator>>=(TaggedInteger const& rhs) noexcept
tagged_integer&
operator>>=(tagged_integer const& rhs) noexcept
{
value_ >>= rhs.value_;
m_value >>= rhs.m_value;
return *this;
}
TaggedInteger
tagged_integer
operator~() const noexcept
{
return TaggedInteger{~value_};
return tagged_integer{~m_value};
}
TaggedInteger
tagged_integer
operator+() const noexcept
{
return *this;
}
TaggedInteger
tagged_integer
operator-() const noexcept
{
return TaggedInteger{-value_};
return tagged_integer{-m_value};
}
TaggedInteger&
tagged_integer&
operator++() noexcept
{
++value_;
++m_value;
return *this;
}
TaggedInteger&
tagged_integer&
operator--() noexcept
{
--value_;
--m_value;
return *this;
}
explicit
operator Int() const noexcept
{
return value_;
return m_value;
}
friend std::ostream&
operator<<(std::ostream& s, TaggedInteger const& t)
operator<<(std::ostream& s, tagged_integer const& t)
{
s << t.value_;
s << t.m_value;
return s;
}
friend std::istream&
operator>>(std::istream& s, TaggedInteger& t)
operator>>(std::istream& s, tagged_integer& t)
{
s >> t.value_;
s >> t.m_value;
return s;
}
friend std::string
to_string(TaggedInteger const& t)
to_string(tagged_integer const& t)
{
return std::to_string(t.value_);
return std::to_string(t.m_value);
}
};
@@ -195,10 +195,10 @@ public:
namespace beast {
template <class Int, class Tag, class HashAlgorithm>
struct IsContiguouslyHashable<xrpl::TaggedInteger<Int, Tag>, HashAlgorithm>
: public IsContiguouslyHashable<Int, HashAlgorithm>
struct is_contiguously_hashable<xrpl::tagged_integer<Int, Tag>, HashAlgorithm>
: public is_contiguously_hashable<Int, HashAlgorithm>
{
explicit IsContiguouslyHashable() = default;
explicit is_contiguously_hashable() = default;
};
} // namespace beast

View File

@@ -15,44 +15,44 @@ namespace beast {
/** Measures handler latency on an io_context queue. */
template <class Clock>
class IoLatencyProbe
class io_latency_probe
{
private:
using duration = typename Clock::duration;
using time_point = typename Clock::time_point;
std::recursive_mutex mutex_;
std::condition_variable_any cond_;
std::size_t count_{1};
duration const period_;
boost::asio::io_context& ios_;
boost::asio::basic_waitable_timer<std::chrono::steady_clock> timer_;
bool cancel_{false};
std::recursive_mutex m_mutex;
std::condition_variable_any m_cond;
std::size_t m_count{1};
duration const m_period;
boost::asio::io_context& m_ios;
boost::asio::basic_waitable_timer<std::chrono::steady_clock> m_timer;
bool m_cancel{false};
public:
IoLatencyProbe(duration const& period, boost::asio::io_context& ios)
: period_(period), ios_(ios), timer_(ios_)
io_latency_probe(duration const& period, boost::asio::io_context& ios)
: m_period(period), m_ios(ios), m_timer(m_ios)
{
}
~IoLatencyProbe()
~io_latency_probe()
{
std::unique_lock<decltype(mutex_)> lock(mutex_);
std::unique_lock<decltype(m_mutex)> lock(m_mutex);
cancel(lock, true);
}
/** Return the io_context associated with the latency probe. */
/** @{ */
boost::asio::io_context&
getIoContext()
get_io_context()
{
return ios_;
return m_ios;
}
[[nodiscard]] boost::asio::io_context const&
getIoContext() const
boost::asio::io_context const&
get_io_context() const
{
return ios_;
return m_ios;
}
/** @} */
@@ -63,14 +63,14 @@ public:
void
cancel()
{
std::unique_lock<decltype(mutex_)> lock(mutex_);
std::unique_lock<decltype(m_mutex)> lock(m_mutex);
cancel(lock, true);
}
void
cancelAsync()
cancel_async()
{
std::unique_lock<decltype(mutex_)> lock(mutex_);
std::unique_lock<decltype(m_mutex)> lock(m_mutex);
cancel(lock, false);
}
/** @} */
@@ -81,13 +81,13 @@ public:
*/
template <class Handler>
void
sampleOne(Handler&& handler)
sample_one(Handler&& handler)
{
std::scoped_lock const lock(mutex_);
if (cancel_)
std::lock_guard const lock(m_mutex);
if (m_cancel)
throw std::logic_error("io_latency_probe is canceled");
boost::asio::post(
ios_, SampleOp<Handler>(std::forward<Handler>(handler), Clock::now(), false, this));
m_ios, sample_op<Handler>(std::forward<Handler>(handler), Clock::now(), false, this));
}
/** Initiate continuous i/o latency sampling.
@@ -98,123 +98,125 @@ public:
void
sample(Handler&& handler)
{
std::scoped_lock const lock(mutex_);
if (cancel_)
std::lock_guard const lock(m_mutex);
if (m_cancel)
throw std::logic_error("io_latency_probe is canceled");
boost::asio::post(
ios_, SampleOp<Handler>(std::forward<Handler>(handler), Clock::now(), true, this));
m_ios, sample_op<Handler>(std::forward<Handler>(handler), Clock::now(), true, this));
}
private:
void
cancel(std::unique_lock<decltype(mutex_)>& lock, bool wait)
cancel(std::unique_lock<decltype(m_mutex)>& lock, bool wait)
{
if (!cancel_)
if (!m_cancel)
{
--count_;
cancel_ = true;
--m_count;
m_cancel = true;
}
if (wait)
cond_.wait(lock, [this] { return this->count_ == 0; });
m_cond.wait(lock, [this] { return this->m_count == 0; });
}
void
addref()
{
std::scoped_lock const lock(mutex_);
++count_;
std::lock_guard const lock(m_mutex);
++m_count;
}
void
release()
{
std::scoped_lock const lock(mutex_);
if (--count_ == 0)
cond_.notify_all();
std::lock_guard const lock(m_mutex);
if (--m_count == 0)
m_cond.notify_all();
}
template <class Handler>
struct SampleOp
struct sample_op
{
Handler handler;
time_point start;
bool repeat;
IoLatencyProbe* probe;
Handler m_handler;
time_point m_start;
bool m_repeat;
io_latency_probe* m_probe;
SampleOp(
sample_op(
Handler const& handler,
time_point const& start,
bool repeat,
IoLatencyProbe* probe)
: handler(handler), start(start), repeat(repeat), probe(probe)
io_latency_probe* probe)
: m_handler(handler), m_start(start), m_repeat(repeat), m_probe(probe)
{
XRPL_ASSERT(
probe,
m_probe,
"beast::io_latency_probe::sample_op::sample_op : non-null "
"probe input");
probe->addref();
m_probe->addref();
}
SampleOp(SampleOp&& from) noexcept
: handler(std::move(from.handler))
, start(from.start)
, repeat(from.repeat)
, probe(from.probe)
sample_op(sample_op&& from) noexcept
: m_handler(std::move(from.m_handler))
, m_start(from.m_start)
, m_repeat(from.m_repeat)
, m_probe(from.m_probe)
{
XRPL_ASSERT(
probe,
m_probe,
"beast::io_latency_probe::sample_op::sample_op(sample_op&&) : "
"non-null probe input");
from.probe = nullptr;
from.m_probe = nullptr;
}
SampleOp(SampleOp const&) = delete;
SampleOp
operator=(SampleOp const&) = delete;
SampleOp&
operator=(SampleOp&&) = delete;
sample_op(sample_op const&) = delete;
sample_op
operator=(sample_op const&) = delete;
sample_op&
operator=(sample_op&&) = delete;
~SampleOp()
~sample_op()
{
if (probe)
probe->release();
if (m_probe)
m_probe->release();
}
void
operator()() const
{
if (probe == nullptr)
if (m_probe == nullptr)
return;
typename Clock::time_point const now(Clock::now());
typename Clock::duration const elapsed(now - start);
typename Clock::duration const elapsed(now - m_start);
handler(elapsed);
m_handler(elapsed);
{
std::scoped_lock const lock(probe->mutex_);
if (probe->cancel_)
std::lock_guard const lock(m_probe->m_mutex);
if (m_probe->m_cancel)
return;
}
if (repeat)
if (m_repeat)
{
// Calculate when we want to sample again, and
// adjust for the expected latency.
//
typename Clock::time_point const when(now + probe->period_ - (2 * elapsed));
typename Clock::time_point const when(now + m_probe->m_period - (2 * elapsed));
if (when <= now)
{
// The latency is too high to maintain the desired
// period so don't bother with a timer.
//
boost::asio::post(probe->ios_, SampleOp<Handler>(handler, now, repeat, probe));
boost::asio::post(
m_probe->m_ios, sample_op<Handler>(m_handler, now, m_repeat, m_probe));
}
else
{
probe->timer_.expires_after(when - now);
probe->timer_.async_wait(SampleOp<Handler>(handler, now, repeat, probe));
m_probe->m_timer.expires_after(when - now);
m_probe->m_timer.async_wait(
sample_op<Handler>(m_handler, now, m_repeat, m_probe));
}
}
}
@@ -222,10 +224,11 @@ private:
void
operator()(boost::system::error_code const& ec)
{
if (probe == nullptr)
if (m_probe == nullptr)
return;
typename Clock::time_point const now(Clock::now());
boost::asio::post(probe->ios_, SampleOp<Handler>(handler, now, repeat, probe));
boost::asio::post(
m_probe->m_ios, sample_op<Handler>(m_handler, now, m_repeat, m_probe));
}
};
};

View File

@@ -31,7 +31,7 @@ namespace beast {
http://en.cppreference.com/w/cpp/concept/Clock
*/
template <class Clock>
class AbstractClock
class abstract_clock
{
public:
using rep = typename Clock::rep;
@@ -40,11 +40,11 @@ public:
using time_point = typename Clock::time_point;
using clock_type = Clock;
static bool const is_steady = Clock::is_steady; // NOLINT(readability-identifier-naming)
static bool const is_steady = Clock::is_steady;
virtual ~AbstractClock() = default;
AbstractClock() = default;
AbstractClock(AbstractClock const&) = default;
virtual ~abstract_clock() = default;
abstract_clock() = default;
abstract_clock(abstract_clock const&) = default;
/** Returns the current time. */
[[nodiscard]] virtual time_point
@@ -56,14 +56,14 @@ public:
namespace detail {
template <class Facade, class Clock>
struct AbstractClockWrapper : public AbstractClock<Facade>
struct abstract_clock_wrapper : public abstract_clock<Facade>
{
explicit AbstractClockWrapper() = default;
explicit abstract_clock_wrapper() = default;
using typename AbstractClock<Facade>::duration;
using typename AbstractClock<Facade>::time_point;
using typename abstract_clock<Facade>::duration;
using typename abstract_clock<Facade>::time_point;
[[nodiscard]] time_point
time_point
now() const override
{
return Clock::now();
@@ -80,11 +80,11 @@ struct AbstractClockWrapper : public AbstractClock<Facade>
@tparam Clock The actual concrete clock to use.
*/
template <class Facade, class Clock = Facade>
AbstractClock<Facade>&
getAbstractClock()
abstract_clock<Facade>&
get_abstract_clock()
{
static detail::AbstractClockWrapper<Facade, Clock> kCLOCK;
return kCLOCK;
static detail::abstract_clock_wrapper<Facade, Clock> clock;
return clock;
}
} // namespace beast

View File

@@ -13,20 +13,19 @@ namespace beast {
@tparam Clock A type meeting these requirements:
http://en.cppreference.com/w/cpp/concept/Clock
*/
class BasicSecondsClock
class basic_seconds_clock
{
public:
using Clock = std::chrono::steady_clock;
explicit BasicSecondsClock() = default;
explicit basic_seconds_clock() = default;
using rep = typename Clock::rep;
using period = typename Clock::period;
using duration = typename Clock::duration;
using time_point = typename Clock::time_point;
static bool const is_steady = // NOLINT(readability-identifier-naming)
Clock::is_steady;
static bool const is_steady = Clock::is_steady;
static time_point
now();

View File

@@ -17,22 +17,22 @@ namespace beast {
http://en.cppreference.com/w/cpp/concept/Clock
*/
template <class Clock>
class ManualClock : public AbstractClock<Clock>
class manual_clock : public abstract_clock<Clock>
{
public:
using typename AbstractClock<Clock>::rep;
using typename AbstractClock<Clock>::duration;
using typename AbstractClock<Clock>::time_point;
using typename abstract_clock<Clock>::rep;
using typename abstract_clock<Clock>::duration;
using typename abstract_clock<Clock>::time_point;
private:
time_point now_;
public:
explicit ManualClock(time_point const& now = time_point(duration(0))) : now_(now)
explicit manual_clock(time_point const& now = time_point(duration(0))) : now_(now)
{
}
[[nodiscard]] time_point
time_point
now() const override
{
return now_;
@@ -44,16 +44,16 @@ public:
{
XRPL_ASSERT(
!Clock::is_steady || when >= now_,
"beast::ManualClock::set(time_point) : forward input");
"beast::manual_clock::set(time_point) : forward input");
now_ = when;
}
/** Convenience for setting the time in seconds from epoch. */
template <class Integer>
void
set(Integer secondsFromEpoch)
set(Integer seconds_from_epoch)
{
set(time_point(duration(std::chrono::seconds(secondsFromEpoch))));
set(time_point(duration(std::chrono::seconds(seconds_from_epoch))));
}
/** Advance the clock by a duration. */
@@ -63,12 +63,12 @@ public:
{
XRPL_ASSERT(
!Clock::is_steady || (now_ + elapsed) >= now_,
"beast::ManualClock::advance(duration) : forward input");
"beast::manual_clock::advance(duration) : forward input");
now_ += elapsed;
}
/** Convenience for advancing the clock by one second. */
ManualClock&
manual_clock&
operator++()
{
advance(std::chrono::seconds(1));

View File

@@ -5,9 +5,9 @@
namespace beast {
template <class T>
struct IsAgedContainer : std::false_type
struct is_aged_container : std::false_type
{
explicit IsAgedContainer() = default;
explicit is_aged_container() = default;
};
} // namespace beast

View File

@@ -9,7 +9,7 @@ namespace beast {
/** Expire aged container items past the specified age. */
template <class AgedContainer, class Rep, class Period>
std::enable_if_t<IsAgedContainer<AgedContainer>::value, std::size_t>
std::enable_if_t<is_aged_container<AgedContainer>::value, std::size_t>
expire(AgedContainer& c, std::chrono::duration<Rep, Period> const& age)
{
std::size_t n(0);

View File

@@ -14,6 +14,6 @@ template <
class Clock = std::chrono::steady_clock,
class Compare = std::less<Key>,
class Allocator = std::allocator<std::pair<Key const, T>>>
using aged_map = detail::AgedOrderedContainer<false, true, Key, T, Clock, Compare, Allocator>;
using aged_map = detail::aged_ordered_container<false, true, Key, T, Clock, Compare, Allocator>;
} // namespace beast

View File

@@ -14,6 +14,6 @@ template <
class Clock = std::chrono::steady_clock,
class Compare = std::less<Key>,
class Allocator = std::allocator<std::pair<Key const, T>>>
using aged_multimap = detail::AgedOrderedContainer<true, true, Key, T, Clock, Compare, Allocator>;
using aged_multimap = detail::aged_ordered_container<true, true, Key, T, Clock, Compare, Allocator>;
} // namespace beast

View File

@@ -14,6 +14,5 @@ template <
class Compare = std::less<Key>,
class Allocator = std::allocator<Key>>
using aged_multiset =
detail::AgedOrderedContainer<true, false, Key, void, Clock, Compare, Allocator>;
detail::aged_ordered_container<true, false, Key, void, Clock, Compare, Allocator>;
} // namespace beast

View File

@@ -13,6 +13,6 @@ template <
class Clock = std::chrono::steady_clock,
class Compare = std::less<Key>,
class Allocator = std::allocator<Key>>
using aged_set = detail::AgedOrderedContainer<false, false, Key, void, Clock, Compare, Allocator>;
using aged_set = detail::aged_ordered_container<false, false, Key, void, Clock, Compare, Allocator>;
} // namespace beast

View File

@@ -16,6 +16,5 @@ template <
class KeyEqual = std::equal_to<Key>,
class Allocator = std::allocator<std::pair<Key const, T>>>
using aged_unordered_map =
detail::AgedUnorderedContainer<false, true, Key, T, Clock, Hash, KeyEqual, Allocator>;
detail::aged_unordered_container<false, true, Key, T, Clock, Hash, KeyEqual, Allocator>;
} // namespace beast

View File

@@ -16,6 +16,5 @@ template <
class KeyEqual = std::equal_to<Key>,
class Allocator = std::allocator<std::pair<Key const, T>>>
using aged_unordered_multimap =
detail::AgedUnorderedContainer<true, true, Key, T, Clock, Hash, KeyEqual, Allocator>;
detail::aged_unordered_container<true, true, Key, T, Clock, Hash, KeyEqual, Allocator>;
} // namespace beast

View File

@@ -15,6 +15,6 @@ template <
class KeyEqual = std::equal_to<Key>,
class Allocator = std::allocator<Key>>
using aged_unordered_multiset =
detail::AgedUnorderedContainer<true, false, Key, void, Clock, Hash, KeyEqual, Allocator>;
detail::aged_unordered_container<true, false, Key, void, Clock, Hash, KeyEqual, Allocator>;
} // namespace beast

View File

@@ -15,6 +15,5 @@ template <
class KeyEqual = std::equal_to<Key>,
class Allocator = std::allocator<Key>>
using aged_unordered_set =
detail::AgedUnorderedContainer<false, false, Key, void, Clock, Hash, KeyEqual, Allocator>;
detail::aged_unordered_container<false, false, Key, void, Clock, Hash, KeyEqual, Allocator>;
} // namespace beast

View File

@@ -3,10 +3,10 @@
namespace beast::detail {
// Extracts the key portion of value
template <bool MaybeMap>
struct AgedAssociativeContainerExtractT
template <bool maybe_map>
struct aged_associative_container_extract_t
{
explicit AgedAssociativeContainerExtractT() = default;
explicit aged_associative_container_extract_t() = default;
template <class Value>
decltype(Value::first) const&
@@ -17,9 +17,9 @@ struct AgedAssociativeContainerExtractT
};
template <>
struct AgedAssociativeContainerExtractT<false>
struct aged_associative_container_extract_t<false>
{
explicit AgedAssociativeContainerExtractT() = default;
explicit aged_associative_container_extract_t() = default;
template <class Value>
Value const&

View File

@@ -12,136 +12,137 @@ class aged_ordered_container;
namespace detail {
// If Iterator is SCARY then this iterator will be as well.
template <bool IsConst, class Iterator>
class AgedContainerIterator
template <bool is_const, class Iterator>
class aged_container_iterator
{
public:
using iterator_category = typename std::iterator_traits<Iterator>::iterator_category;
using value_type = std::conditional_t<
IsConst,
typename Iterator::value_type::Stashed::value_type const,
typename Iterator::value_type::Stashed::value_type>;
is_const,
typename Iterator::value_type::stashed::value_type const,
typename Iterator::value_type::stashed::value_type>;
using difference_type = typename std::iterator_traits<Iterator>::difference_type;
using pointer = value_type*;
using reference = value_type&;
using time_point = typename Iterator::value_type::Stashed::time_point;
using time_point = typename Iterator::value_type::stashed::time_point;
AgedContainerIterator() = default;
aged_container_iterator() = default;
// Disable constructing a const_iterator from a non-const_iterator.
// Converting between reverse and non-reverse iterators should be explicit.
template <
bool OtherIsConst,
bool other_is_const,
class OtherIterator,
class = std::enable_if_t<
(!OtherIsConst || IsConst) &&
(!other_is_const || is_const) &&
!static_cast<bool>(std::is_same_v<Iterator, OtherIterator>)>>
explicit AgedContainerIterator(AgedContainerIterator<OtherIsConst, OtherIterator> const& other)
: iter_(other.iter_)
explicit aged_container_iterator(
aged_container_iterator<other_is_const, OtherIterator> const& other)
: m_iter(other.m_iter)
{
}
// Disable constructing a const_iterator from a non-const_iterator.
template <bool OtherIsConst, class = std::enable_if_t<!OtherIsConst || IsConst>>
AgedContainerIterator(AgedContainerIterator<OtherIsConst, Iterator> const& other)
: iter_(other.iter_)
template <bool other_is_const, class = std::enable_if_t<!other_is_const || is_const>>
aged_container_iterator(aged_container_iterator<other_is_const, Iterator> const& other)
: m_iter(other.m_iter)
{
}
// Disable assigning a const_iterator to a non-const iterator
template <bool OtherIsConst, class OtherIterator>
template <bool other_is_const, class OtherIterator>
auto
operator=(AgedContainerIterator<OtherIsConst, OtherIterator> const& other)
-> std::enable_if_t<!OtherIsConst || IsConst, AgedContainerIterator&>
operator=(aged_container_iterator<other_is_const, OtherIterator> const& other)
-> std::enable_if_t<!other_is_const || is_const, aged_container_iterator&>
{
iter_ = other.iter_;
m_iter = other.m_iter;
return *this;
}
template <bool OtherIsConst, class OtherIterator>
template <bool other_is_const, class OtherIterator>
bool
operator==(AgedContainerIterator<OtherIsConst, OtherIterator> const& other) const
operator==(aged_container_iterator<other_is_const, OtherIterator> const& other) const
{
return iter_ == other.iter_;
return m_iter == other.m_iter;
}
template <bool OtherIsConst, class OtherIterator>
template <bool other_is_const, class OtherIterator>
bool
operator!=(AgedContainerIterator<OtherIsConst, OtherIterator> const& other) const
operator!=(aged_container_iterator<other_is_const, OtherIterator> const& other) const
{
return iter_ != other.iter_;
return m_iter != other.m_iter;
}
AgedContainerIterator&
aged_container_iterator&
operator++()
{
++iter_;
++m_iter;
return *this;
}
AgedContainerIterator
aged_container_iterator
operator++(int)
{
AgedContainerIterator const prev(*this);
++iter_;
aged_container_iterator const prev(*this);
++m_iter;
return prev;
}
AgedContainerIterator&
aged_container_iterator&
operator--()
{
--iter_;
--m_iter;
return *this;
}
AgedContainerIterator
aged_container_iterator
operator--(int)
{
AgedContainerIterator const prev(*this);
--iter_;
aged_container_iterator const prev(*this);
--m_iter;
return prev;
}
reference
operator*() const
{
return iter_->value;
return m_iter->value;
}
pointer
operator->() const
{
return &iter_->value;
return &m_iter->value;
}
[[nodiscard]] time_point const&
time_point const&
when() const
{
return iter_->when;
return m_iter->when;
}
private:
template <bool, bool, class, class, class, class, class>
friend class AgedOrderedContainer;
friend class aged_ordered_container;
template <bool, bool, class, class, class, class, class, class>
friend class AgedUnorderedContainer;
friend class aged_unordered_container;
template <bool, class>
friend class AgedContainerIterator;
friend class aged_container_iterator;
template <class OtherIterator>
AgedContainerIterator(OtherIterator iter) : iter_(std::move(iter))
aged_container_iterator(OtherIterator iter) : m_iter(std::move(iter))
{
}
[[nodiscard]] Iterator const&
Iterator const&
iterator() const
{
return iter_;
return m_iter;
}
Iterator iter_;
Iterator m_iter;
};
} // namespace detail

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -14,25 +14,25 @@
namespace beast::detail {
template <class T>
struct IsEmptyBaseOptimizationDerived
struct is_empty_base_optimization_derived
: std::integral_constant<bool, std::is_empty_v<T> && !boost::is_final<T>::value>
{
};
template <class T, int UniqueID = 0, bool IsDerived = IsEmptyBaseOptimizationDerived<T>::value>
class EmptyBaseOptimization : private T
template <class T, int UniqueID = 0, bool isDerived = is_empty_base_optimization_derived<T>::value>
class empty_base_optimization : private T
{
public:
EmptyBaseOptimization() = default;
EmptyBaseOptimization(EmptyBaseOptimization&&) = default;
EmptyBaseOptimization(EmptyBaseOptimization const&) = default;
EmptyBaseOptimization&
operator=(EmptyBaseOptimization&&) = default;
EmptyBaseOptimization&
operator=(EmptyBaseOptimization const&) = default;
empty_base_optimization() = default;
empty_base_optimization(empty_base_optimization&&) = default;
empty_base_optimization(empty_base_optimization const&) = default;
empty_base_optimization&
operator=(empty_base_optimization&&) = default;
empty_base_optimization&
operator=(empty_base_optimization const&) = default;
template <class Arg1, class... ArgN>
explicit EmptyBaseOptimization(Arg1&& arg1, ArgN&&... argn)
explicit empty_base_optimization(Arg1&& arg1, ArgN&&... argn)
: T(std::forward<Arg1>(arg1), std::forward<ArgN>(argn)...)
{
}
@@ -43,7 +43,7 @@ public:
return *this;
}
[[nodiscard]] T const&
T const&
member() const noexcept
{
return *this;
@@ -53,21 +53,21 @@ public:
//------------------------------------------------------------------------------
template <class T, int UniqueID>
class EmptyBaseOptimization<T, UniqueID, false>
class empty_base_optimization<T, UniqueID, false>
{
T t_;
public:
EmptyBaseOptimization() = default;
EmptyBaseOptimization(EmptyBaseOptimization&&) = default;
EmptyBaseOptimization(EmptyBaseOptimization const&) = default;
EmptyBaseOptimization&
operator=(EmptyBaseOptimization&&) = default;
EmptyBaseOptimization&
operator=(EmptyBaseOptimization const&) = default;
empty_base_optimization() = default;
empty_base_optimization(empty_base_optimization&&) = default;
empty_base_optimization(empty_base_optimization const&) = default;
empty_base_optimization&
operator=(empty_base_optimization&&) = default;
empty_base_optimization&
operator=(empty_base_optimization const&) = default;
template <class Arg1, class... ArgN>
explicit EmptyBaseOptimization(Arg1&& arg1, ArgN&&... argn)
explicit empty_base_optimization(Arg1&& arg1, ArgN&&... argn)
: t_(std::forward<Arg1>(arg1), std::forward<ArgN>(argn)...)
{
}

View File

@@ -21,7 +21,7 @@ setCurrentThreadName(std::string_view newThreadName);
// On Linux, thread names are limited to 16 bytes including the null terminator.
// Maximum number of characters is therefore 15.
constexpr std::size_t kMAX_THREAD_NAME_LENGTH = 15;
constexpr std::size_t maxThreadNameLength = 15;
/** Sets the name of the caller thread with compile-time size checking.
@tparam N The size of the string literal including null terminator
@@ -34,7 +34,7 @@ template <std::size_t N>
void
setCurrentThreadName(char const (&newThreadName)[N])
{
static_assert(N <= kMAX_THREAD_NAME_LENGTH + 1, "Thread name cannot exceed 15 characters");
static_assert(N <= maxThreadNameLength + 1, "Thread name cannot exceed 15 characters");
setCurrentThreadName(std::string_view(newThreadName, N - 1));
}

View File

@@ -45,8 +45,8 @@ class ListNode
template <typename>
friend class ListIterator;
ListNode* next_ = nullptr;
ListNode* prev_ = nullptr;
ListNode* m_next = nullptr;
ListNode* m_prev = nullptr;
};
//------------------------------------------------------------------------------
@@ -62,12 +62,12 @@ public:
using reference = value_type&;
using size_type = std::size_t;
ListIterator(N* node = nullptr) noexcept : node_(node)
ListIterator(N* node = nullptr) noexcept : m_node(node)
{
}
template <typename M>
ListIterator(ListIterator<M> const& other) noexcept : node_(other.node_)
ListIterator(ListIterator<M> const& other) noexcept : m_node(other.m_node)
{
}
@@ -75,7 +75,7 @@ public:
bool
operator==(ListIterator<M> const& other) const noexcept
{
return node_ == other.node_;
return m_node == other.m_node;
}
template <typename M>
@@ -128,25 +128,25 @@ public:
}
private:
[[nodiscard]] reference
reference
dereference() const noexcept
{
return static_cast<reference>(*node_);
return static_cast<reference>(*m_node);
}
void
increment() noexcept
{
node_ = node_->next_;
m_node = m_node->m_next;
}
void
decrement() noexcept
{
node_ = node_->prev_;
m_node = m_node->m_prev;
}
N* node_;
N* m_node;
};
} // namespace detail
@@ -161,11 +161,11 @@ private:
struct Object : List <Object>::Node
{
explicit Object (int value) : value_ (value)
explicit Object (int value) : m_value (value)
{
}
int value_;
int m_value;
};
@endcode
@@ -190,7 +190,7 @@ private:
@code
for (List <Object>::iterator iter = list.begin(); iter != list.end; ++iter)
std::cout << iter->value_;
std::cout << iter->m_value;
@endcode
@@ -199,10 +199,10 @@ private:
@code
BOOST_FOREACH (Object& object, list) // boost only
std::cout << object.value_;
std::cout << object.m_value;
for (Object& object : list) // C++11 only
std::cout << object.value_;
std::cout << object.m_value;
@endcode
@@ -275,8 +275,8 @@ public:
/** Create an empty list. */
List()
{
head_.prev_ = nullptr; // identifies the head
tail_.next_ = nullptr; // identifies the tail
m_head.m_prev = nullptr; // identifies the head
m_tail.m_next = nullptr; // identifies the tail
clear();
}
@@ -287,17 +287,17 @@ public:
/** Determine if the list is empty.
@return `true` if the list is empty.
*/
[[nodiscard]] bool
bool
empty() const noexcept
{
return size() == 0;
}
/** Returns the number of elements in the list. */
[[nodiscard]] size_type
size_type
size() const noexcept
{
return size_;
return m_size;
}
/** Obtain a reference to the first element.
@@ -307,17 +307,17 @@ public:
reference
front() noexcept
{
return element_from(head_.next_);
return element_from(m_head.m_next);
}
/** Obtain a const reference to the first element.
@invariant The list may not be empty.
@return A const reference to the first element.
*/
[[nodiscard]] const_reference
const_reference
front() const noexcept
{
return element_from(head_.next_);
return element_from(m_head.m_next);
}
/** Obtain a reference to the last element.
@@ -327,17 +327,17 @@ public:
reference
back() noexcept
{
return element_from(tail_.prev_);
return element_from(m_tail.m_prev);
}
/** Obtain a const reference to the last element.
@invariant The list may not be empty.
@return A const reference to the last element.
*/
[[nodiscard]] const_reference
const_reference
back() const noexcept
{
return element_from(tail_.prev_);
return element_from(m_tail.m_prev);
}
/** Obtain an iterator to the beginning of the list.
@@ -346,25 +346,25 @@ public:
iterator
begin() noexcept
{
return iterator(head_.next_);
return iterator(m_head.m_next);
}
/** Obtain a const iterator to the beginning of the list.
@return A const iterator pointing to the beginning of the list.
*/
[[nodiscard]] const_iterator
const_iterator
begin() const noexcept
{
return const_iterator(head_.next_);
return const_iterator(m_head.m_next);
}
/** Obtain a const iterator to the beginning of the list.
@return A const iterator pointing to the beginning of the list.
*/
[[nodiscard]] const_iterator
const_iterator
cbegin() const noexcept
{
return const_iterator(head_.next_);
return const_iterator(m_head.m_next);
}
/** Obtain a iterator to the end of the list.
@@ -373,25 +373,25 @@ public:
iterator
end() noexcept
{
return iterator(&tail_);
return iterator(&m_tail);
}
/** Obtain a const iterator to the end of the list.
@return A constiterator pointing to the end of the list.
*/
[[nodiscard]] const_iterator
const_iterator
end() const noexcept
{
return const_iterator(&tail_);
return const_iterator(&m_tail);
}
/** Obtain a const iterator to the end of the list
@return A constiterator pointing to the end of the list.
*/
[[nodiscard]] const_iterator
const_iterator
cend() const noexcept
{
return const_iterator(&tail_);
return const_iterator(&m_tail);
}
/** Clear the list.
@@ -400,9 +400,9 @@ public:
void
clear() noexcept
{
head_.next_ = &tail_;
tail_.prev_ = &head_;
size_ = 0;
m_head.m_next = &m_tail;
m_tail.m_prev = &m_head;
m_size = 0;
}
/** Insert an element.
@@ -415,11 +415,11 @@ public:
insert(iterator pos, T& element) noexcept
{
Node* node = static_cast<Node*>(&element);
node->next_ = &*pos;
node->prev_ = node->next_->prev_;
node->next_->prev_ = node;
node->prev_->next_ = node;
++size_;
node->m_next = &*pos;
node->m_prev = node->m_next->m_prev;
node->m_next->m_prev = node;
node->m_prev->m_next = node;
++m_size;
return iterator(node);
}
@@ -434,11 +434,11 @@ public:
if (!other.empty())
{
Node* before = &*pos;
other.head_.next_->prev_ = before->prev_;
before->prev_->next_ = other.head_.next_;
other.tail_.prev_->next_ = before;
before->prev_ = other.tail_.prev_;
size_ += other.size_;
other.m_head.m_next->m_prev = before->m_prev;
before->m_prev->m_next = other.m_head.m_next;
other.m_tail.m_prev->m_next = before;
before->m_prev = other.m_tail.m_prev;
m_size += other.m_size;
other.clear();
}
}
@@ -453,9 +453,9 @@ public:
{
Node const* node = &*pos;
++pos;
node->next_->prev_ = node->prev_;
node->prev_->next_ = node->next_;
--size_;
node->m_next->m_prev = node->m_prev;
node->m_prev->m_next = node->m_next;
--m_size;
return pos;
}
@@ -464,7 +464,7 @@ public:
@param element The element to insert.
*/
iterator
pushFront(T& element) noexcept
push_front(T& element) noexcept
{
return insert(begin(), element);
}
@@ -474,7 +474,7 @@ public:
@return A reference to the popped element.
*/
T&
popFront() noexcept
pop_front() noexcept
{
T& element(front());
erase(begin());
@@ -486,7 +486,7 @@ public:
@param element The element to append.
*/
iterator
pushBack(T& element) noexcept
push_back(T& element) noexcept
{
return insert(end(), element);
}
@@ -496,7 +496,7 @@ public:
@return A reference to the popped element.
*/
T&
popBack() noexcept
pop_back() noexcept
{
T& element(back());
erase(--end());
@@ -539,7 +539,7 @@ public:
@return An iterator to the element.
*/
iterator
iteratorTo(T& element) const noexcept
iterator_to(T& element) const noexcept
{
return iterator(static_cast<Node*>(&element));
}
@@ -549,29 +549,29 @@ public:
@param element The element to obtain an iterator for.
@return A const iterator to the element.
*/
[[nodiscard]] const_iterator
constIteratorTo(T const& element) const noexcept
const_iterator
const_iterator_to(T const& element) const noexcept
{
return const_iterator(static_cast<Node const*>(&element));
}
private:
reference
elementFrom(Node* node) noexcept
element_from(Node* node) noexcept
{
return *(static_cast<pointer>(node));
}
const_reference
elementFrom(Node const* node) const noexcept
element_from(Node const* node) const noexcept
{
return *(static_cast<const_pointer>(node));
}
private:
size_type size_ = 0u;
Node head_;
Node tail_;
size_type m_size = 0u;
Node m_head;
Node m_tail;
};
} // namespace beast

View File

@@ -26,27 +26,27 @@ public:
LockFreeStackIterator() = default;
LockFreeStackIterator(NodePtr node) : node_(node)
LockFreeStackIterator(NodePtr node) : m_node(node)
{
}
template <bool OtherIsConst>
explicit LockFreeStackIterator(LockFreeStackIterator<Container, OtherIsConst> const& other)
: node_(other.node_)
: m_node(other.m_node)
{
}
LockFreeStackIterator&
operator=(NodePtr node)
{
node_ = node;
m_node = node;
return static_cast<LockFreeStackIterator&>(*this);
}
LockFreeStackIterator&
operator++()
{
node_ = node_->next_.load();
m_node = m_node->m_next.load();
return static_cast<LockFreeStackIterator&>(*this);
}
@@ -54,14 +54,14 @@ public:
operator++(int)
{
LockFreeStackIterator result(*this);
node_ = node_->next_;
m_node = m_node->m_next;
return result;
}
NodePtr
node() const
{
return node_;
return m_node;
}
reference
@@ -73,11 +73,11 @@ public:
pointer
operator->() const
{
return static_cast<pointer>(node_);
return static_cast<pointer>(m_node);
}
private:
NodePtr node_{};
NodePtr m_node{};
};
//------------------------------------------------------------------------------
@@ -121,11 +121,11 @@ public:
class Node
{
public:
Node() : next_(nullptr)
Node() : m_next(nullptr)
{
}
explicit Node(Node* next) : next_(next)
explicit Node(Node* next) : m_next(next)
{
}
@@ -139,7 +139,7 @@ public:
template <class Container, bool IsConst>
friend class LockFreeStackIterator;
std::atomic<Node*> next_;
std::atomic<Node*> m_next;
};
public:
@@ -153,7 +153,7 @@ public:
using iterator = LockFreeStackIterator<LockFreeStack<Element, Tag>, false>;
using const_iterator = LockFreeStackIterator<LockFreeStack<Element, Tag>, true>;
LockFreeStack() : end_(nullptr), head_(&end_)
LockFreeStack() : m_end(nullptr), m_head(&m_end)
{
}
@@ -162,10 +162,10 @@ public:
operator=(LockFreeStack const&) = delete;
/** Returns true if the stack is empty. */
[[nodiscard]] bool
bool
empty() const
{
return head_.load() == &end_;
return m_head.load() == &m_end;
}
/** Push a node onto the stack.
@@ -181,16 +181,16 @@ public:
*/
// VFALCO NOTE Fix this, shouldn't it be a reference like intrusive list?
bool
pushFront(Node* node)
push_front(Node* node)
{
bool first = false;
Node* oldHead = head_.load(std::memory_order_relaxed);
Node* old_head = m_head.load(std::memory_order_relaxed);
do
{
first = (oldHead == &end_);
node->next_ = oldHead;
} while (!head_.compare_exchange_strong(
oldHead, node, std::memory_order_release, std::memory_order_relaxed));
first = (old_head == &m_end);
node->m_next = old_head;
} while (!m_head.compare_exchange_strong(
old_head, node, std::memory_order_release, std::memory_order_relaxed));
return first;
}
@@ -204,17 +204,17 @@ public:
was empty.
*/
Element*
popFront()
pop_front()
{
Node* node = head_.load();
Node* newHead = nullptr;
Node* node = m_head.load();
Node* new_head = nullptr;
do
{
if (node == &end_)
if (node == &m_end)
return nullptr;
newHead = node->next_.load();
} while (!head_.compare_exchange_strong(
node, newHead, std::memory_order_release, std::memory_order_relaxed));
new_head = node->m_next.load();
} while (!m_head.compare_exchange_strong(
node, new_head, std::memory_order_release, std::memory_order_relaxed));
return static_cast<Element*>(node);
}
@@ -228,43 +228,43 @@ public:
iterator
begin()
{
return iterator(head_.load());
return iterator(m_head.load());
}
iterator
end()
{
return iterator(&end_);
return iterator(&m_end);
}
[[nodiscard]] const_iterator
const_iterator
begin() const
{
return const_iterator(head_.load());
return const_iterator(m_head.load());
}
[[nodiscard]] const_iterator
const_iterator
end() const
{
return const_iterator(&end_);
return const_iterator(&m_end);
}
[[nodiscard]] const_iterator
const_iterator
cbegin() const
{
return const_iterator(head_.load());
return const_iterator(m_head.load());
}
[[nodiscard]] const_iterator
const_iterator
cend() const
{
return const_iterator(&end_);
return const_iterator(&m_end);
}
/** @} */
private:
Node end_;
std::atomic<Node*> head_;
Node m_end;
std::atomic<Node*> m_head;
};
} // namespace beast

View File

@@ -37,15 +37,15 @@ public:
parse(std::string_view input);
/** Produce a string from semantic version components. */
[[nodiscard]] std::string
std::string
print() const;
[[nodiscard]] bool
bool
isRelease() const noexcept
{
return preReleaseIdentifiers.empty();
}
[[nodiscard]] bool
bool
isPreRelease() const noexcept
{
return !isRelease();

View File

@@ -24,7 +24,7 @@ namespace detail {
template <class T>
/*constexpr*/
inline void
reverseBytes(T& t)
reverse_bytes(T& t)
{
unsigned char* bytes =
static_cast<unsigned char*>(std::memmove(std::addressof(t), std::addressof(t), sizeof(T)));
@@ -35,14 +35,14 @@ reverseBytes(T& t)
template <class T>
/*constexpr*/
inline void
maybeReverseBytes(T& t, std::false_type)
maybe_reverse_bytes(T& t, std::false_type)
{
}
template <class T>
/*constexpr*/
inline void
maybeReverseBytes(T& t, std::true_type)
maybe_reverse_bytes(T& t, std::true_type)
{
reverse_bytes(t);
}
@@ -50,15 +50,15 @@ maybeReverseBytes(T& t, std::true_type)
template <class T, class Hasher>
/*constexpr*/
inline void
maybeReverseBytes(T& t, Hasher&)
maybe_reverse_bytes(T& t, Hasher&)
{
maybeReverseBytes(
t, std::integral_constant<bool, Hasher::kENDIAN != boost::endian::order::native>{});
maybe_reverse_bytes(
t, std::integral_constant<bool, Hasher::endian != boost::endian::order::native>{});
}
} // namespace detail
// IsUniquelyRepresented<T>
// is_uniquely_represented<T>
// A type T is contiguously hashable if for all combinations of two values of
// a type, say x and y, if x == y, then it must also be true that
@@ -66,78 +66,78 @@ maybeReverseBytes(T& t, Hasher&)
// then x and y have the same bit pattern representation.
template <class T>
struct IsUniquelyRepresented
struct is_uniquely_represented
: public std::integral_constant<
bool,
std::is_integral_v<T> || std::is_enum_v<T> || std::is_pointer_v<T>>
{
explicit IsUniquelyRepresented() = default;
explicit is_uniquely_represented() = default;
};
template <class T>
struct IsUniquelyRepresented<T const> : public IsUniquelyRepresented<T>
struct is_uniquely_represented<T const> : public is_uniquely_represented<T>
{
explicit IsUniquelyRepresented() = default;
explicit is_uniquely_represented() = default;
};
template <class T>
struct IsUniquelyRepresented<T volatile> : public IsUniquelyRepresented<T>
struct is_uniquely_represented<T volatile> : public is_uniquely_represented<T>
{
explicit IsUniquelyRepresented() = default;
explicit is_uniquely_represented() = default;
};
template <class T>
struct IsUniquelyRepresented<T const volatile> : public IsUniquelyRepresented<T>
struct is_uniquely_represented<T const volatile> : public is_uniquely_represented<T>
{
explicit IsUniquelyRepresented() = default;
explicit is_uniquely_represented() = default;
};
// IsUniquelyRepresented<std::pair<T, U>>
// is_uniquely_represented<std::pair<T, U>>
template <class T, class U>
struct IsUniquelyRepresented<std::pair<T, U>>
struct is_uniquely_represented<std::pair<T, U>>
: public std::integral_constant<
bool,
IsUniquelyRepresented<T>::value && IsUniquelyRepresented<U>::value &&
is_uniquely_represented<T>::value && is_uniquely_represented<U>::value &&
sizeof(T) + sizeof(U) == sizeof(std::pair<T, U>)>
{
explicit IsUniquelyRepresented() = default;
explicit is_uniquely_represented() = default;
};
// IsUniquelyRepresented<std::tuple<T...>>
// is_uniquely_represented<std::tuple<T...>>
template <class... T>
struct IsUniquelyRepresented<std::tuple<T...>>
struct is_uniquely_represented<std::tuple<T...>>
: public std::integral_constant<
bool,
std::conjunction_v<IsUniquelyRepresented<T>...> &&
std::conjunction_v<is_uniquely_represented<T>...> &&
sizeof(std::tuple<T...>) == (sizeof(T) + ...)>
{
explicit IsUniquelyRepresented() = default;
explicit is_uniquely_represented() = default;
};
// IsUniquelyRepresented<T[N]>
// is_uniquely_represented<T[N]>
template <class T, std::size_t N>
struct IsUniquelyRepresented<T[N]> : public IsUniquelyRepresented<T>
struct is_uniquely_represented<T[N]> : public is_uniquely_represented<T>
{
explicit IsUniquelyRepresented() = default;
explicit is_uniquely_represented() = default;
};
// IsUniquelyRepresented<std::array<T, N>>
// is_uniquely_represented<std::array<T, N>>
template <class T, std::size_t N>
struct IsUniquelyRepresented<std::array<T, N>>
struct is_uniquely_represented<std::array<T, N>>
: public std::integral_constant<
bool,
IsUniquelyRepresented<T>::value && sizeof(T) * N == sizeof(std::array<T, N>)>
is_uniquely_represented<T>::value && sizeof(T) * N == sizeof(std::array<T, N>)>
{
explicit IsUniquelyRepresented() = default;
explicit is_uniquely_represented() = default;
};
/** Metafunction returning `true` if the type can be hashed in one call.
For `IsContiguouslyHashable<T>::value` to be true, then for every
For `is_contiguously_hashable<T>::value` to be true, then for every
combination of possible values of `T` held in `x` and `y`,
if `x == y`, then it must be true that `memcmp(&x, &y, sizeof(T))`
return 0; i.e. that `x` and `y` are represented by the same bit pattern.
@@ -150,23 +150,23 @@ struct IsUniquelyRepresented<std::array<T, N>>
*/
/** @{ */
template <class T, class HashAlgorithm>
struct IsContiguouslyHashable
struct is_contiguously_hashable
: public std::integral_constant<
bool,
IsUniquelyRepresented<T>::value &&
(sizeof(T) == 1 || HashAlgorithm::kENDIAN == boost::endian::order::native)>
is_uniquely_represented<T>::value &&
(sizeof(T) == 1 || HashAlgorithm::endian == boost::endian::order::native)>
{
explicit IsContiguouslyHashable() = default;
explicit is_contiguously_hashable() = default;
};
template <class T, std::size_t N, class HashAlgorithm>
struct IsContiguouslyHashable<T[N], HashAlgorithm>
struct is_contiguously_hashable<T[N], HashAlgorithm>
: public std::integral_constant<
bool,
IsUniquelyRepresented<T[N]>::value &&
is_uniquely_represented<T[N]>::value &&
(sizeof(T) == 1 || HashAlgorithm::endian == boost::endian::order::native)>
{
explicit IsContiguouslyHashable() = default;
explicit is_contiguously_hashable() = default;
};
/** @} */
@@ -200,7 +200,7 @@ struct IsContiguouslyHashable<T[N], HashAlgorithm>
// scalars
template <class Hasher, class T>
inline std::enable_if_t<IsContiguouslyHashable<T, Hasher>::value>
inline std::enable_if_t<is_contiguously_hashable<T, Hasher>::value>
hash_append(Hasher& h, T const& t) noexcept
{
// NOLINTNEXTLINE(bugprone-sizeof-expression)
@@ -209,11 +209,11 @@ hash_append(Hasher& h, T const& t) noexcept
template <class Hasher, class T>
inline std::enable_if_t<
!IsContiguouslyHashable<T, Hasher>::value &&
!is_contiguously_hashable<T, Hasher>::value &&
(std::is_integral_v<T> || std::is_pointer_v<T> || std::is_enum_v<T>)>
hash_append(Hasher& h, T t) noexcept
{
detail::reverseBytes(t);
detail::reverse_bytes(t);
h(std::addressof(t), sizeof(t));
}
@@ -223,7 +223,7 @@ hash_append(Hasher& h, T t) noexcept
{
if (t == 0)
t = 0;
detail::maybeReverseBytes(t, h);
detail::maybe_reverse_bytes(t, h);
h(&t, sizeof(t));
}
@@ -232,42 +232,42 @@ inline void
hash_append(Hasher& h, std::nullptr_t) noexcept
{
void const* p = nullptr;
detail::maybeReverseBytes(p, h);
detail::maybe_reverse_bytes(p, h);
h(&p, sizeof(p));
}
// Forward declarations for ADL purposes
template <class Hasher, class T, std::size_t N>
std::enable_if_t<!IsContiguouslyHashable<T, Hasher>::value>
std::enable_if_t<!is_contiguously_hashable<T, Hasher>::value>
hash_append(Hasher& h, T (&a)[N]) noexcept;
template <class Hasher, class CharT, class Traits, class Alloc>
std::enable_if_t<!IsContiguouslyHashable<CharT, Hasher>::value>
std::enable_if_t<!is_contiguously_hashable<CharT, Hasher>::value>
hash_append(Hasher& h, std::basic_string<CharT, Traits, Alloc> const& s) noexcept;
template <class Hasher, class CharT, class Traits, class Alloc>
std::enable_if_t<IsContiguouslyHashable<CharT, Hasher>::value>
std::enable_if_t<is_contiguously_hashable<CharT, Hasher>::value>
hash_append(Hasher& h, std::basic_string<CharT, Traits, Alloc> const& s) noexcept;
template <class Hasher, class T, class U>
std::enable_if_t<!IsContiguouslyHashable<std::pair<T, U>, Hasher>::value>
std::enable_if_t<!is_contiguously_hashable<std::pair<T, U>, Hasher>::value>
hash_append(Hasher& h, std::pair<T, U> const& p) noexcept;
template <class Hasher, class T, class Alloc>
std::enable_if_t<!IsContiguouslyHashable<T, Hasher>::value>
std::enable_if_t<!is_contiguously_hashable<T, Hasher>::value>
hash_append(Hasher& h, std::vector<T, Alloc> const& v) noexcept;
template <class Hasher, class T, class Alloc>
std::enable_if_t<IsContiguouslyHashable<T, Hasher>::value>
std::enable_if_t<is_contiguously_hashable<T, Hasher>::value>
hash_append(Hasher& h, std::vector<T, Alloc> const& v) noexcept;
template <class Hasher, class T, std::size_t N>
std::enable_if_t<!IsContiguouslyHashable<std::array<T, N>, Hasher>::value>
std::enable_if_t<!is_contiguously_hashable<std::array<T, N>, Hasher>::value>
hash_append(Hasher& h, std::array<T, N> const& a) noexcept;
template <class Hasher, class... T>
std::enable_if_t<!IsContiguouslyHashable<std::tuple<T...>, Hasher>::value>
std::enable_if_t<!is_contiguously_hashable<std::tuple<T...>, Hasher>::value>
hash_append(Hasher& h, std::tuple<T...> const& t) noexcept;
template <class Hasher, class Key, class T, class Hash, class Pred, class Alloc>
@@ -279,10 +279,10 @@ void
hash_append(Hasher& h, std::unordered_set<Key, Hash, Pred, Alloc> const& s);
template <class Hasher, class Key, class Compare, class Alloc>
std::enable_if_t<!IsContiguouslyHashable<Key, Hasher>::value>
std::enable_if_t<!is_contiguously_hashable<Key, Hasher>::value>
hash_append(Hasher& h, boost::container::flat_set<Key, Compare, Alloc> const& v) noexcept;
template <class Hasher, class Key, class Compare, class Alloc>
std::enable_if_t<IsContiguouslyHashable<Key, Hasher>::value>
std::enable_if_t<is_contiguously_hashable<Key, Hasher>::value>
hash_append(Hasher& h, boost::container::flat_set<Key, Compare, Alloc> const& v) noexcept;
template <class Hasher, class T0, class T1, class... T>
void
@@ -291,7 +291,7 @@ hash_append(Hasher& h, T0 const& t0, T1 const& t1, T const&... t) noexcept;
// c-array
template <class Hasher, class T, std::size_t N>
std::enable_if_t<!IsContiguouslyHashable<T, Hasher>::value>
std::enable_if_t<!is_contiguously_hashable<T, Hasher>::value>
hash_append(Hasher& h, T (&a)[N]) noexcept
{
for (auto const& t : a)
@@ -301,7 +301,7 @@ hash_append(Hasher& h, T (&a)[N]) noexcept
// basic_string
template <class Hasher, class CharT, class Traits, class Alloc>
inline std::enable_if_t<!IsContiguouslyHashable<CharT, Hasher>::value>
inline std::enable_if_t<!is_contiguously_hashable<CharT, Hasher>::value>
hash_append(Hasher& h, std::basic_string<CharT, Traits, Alloc> const& s) noexcept
{
for (auto c : s)
@@ -310,7 +310,7 @@ hash_append(Hasher& h, std::basic_string<CharT, Traits, Alloc> const& s) noexcep
}
template <class Hasher, class CharT, class Traits, class Alloc>
inline std::enable_if_t<IsContiguouslyHashable<CharT, Hasher>::value>
inline std::enable_if_t<is_contiguously_hashable<CharT, Hasher>::value>
hash_append(Hasher& h, std::basic_string<CharT, Traits, Alloc> const& s) noexcept
{
h(s.data(), s.size() * sizeof(CharT));
@@ -320,7 +320,7 @@ hash_append(Hasher& h, std::basic_string<CharT, Traits, Alloc> const& s) noexcep
// pair
template <class Hasher, class T, class U>
inline std::enable_if_t<!IsContiguouslyHashable<std::pair<T, U>, Hasher>::value>
inline std::enable_if_t<!is_contiguously_hashable<std::pair<T, U>, Hasher>::value>
hash_append(Hasher& h, std::pair<T, U> const& p) noexcept
{
hash_append(h, p.first, p.second);
@@ -329,7 +329,7 @@ hash_append(Hasher& h, std::pair<T, U> const& p) noexcept
// vector
template <class Hasher, class T, class Alloc>
inline std::enable_if_t<!IsContiguouslyHashable<T, Hasher>::value>
inline std::enable_if_t<!is_contiguously_hashable<T, Hasher>::value>
hash_append(Hasher& h, std::vector<T, Alloc> const& v) noexcept
{
for (auto const& t : v)
@@ -338,7 +338,7 @@ hash_append(Hasher& h, std::vector<T, Alloc> const& v) noexcept
}
template <class Hasher, class T, class Alloc>
inline std::enable_if_t<IsContiguouslyHashable<T, Hasher>::value>
inline std::enable_if_t<is_contiguously_hashable<T, Hasher>::value>
hash_append(Hasher& h, std::vector<T, Alloc> const& v) noexcept
{
h(v.data(), v.size() * sizeof(T));
@@ -348,7 +348,7 @@ hash_append(Hasher& h, std::vector<T, Alloc> const& v) noexcept
// array
template <class Hasher, class T, std::size_t N>
std::enable_if_t<!IsContiguouslyHashable<std::array<T, N>, Hasher>::value>
std::enable_if_t<!is_contiguously_hashable<std::array<T, N>, Hasher>::value>
hash_append(Hasher& h, std::array<T, N> const& a) noexcept
{
for (auto const& t : a)
@@ -356,14 +356,14 @@ hash_append(Hasher& h, std::array<T, N> const& a) noexcept
}
template <class Hasher, class Key, class Compare, class Alloc>
std::enable_if_t<!IsContiguouslyHashable<Key, Hasher>::value>
std::enable_if_t<!is_contiguously_hashable<Key, Hasher>::value>
hash_append(Hasher& h, boost::container::flat_set<Key, Compare, Alloc> const& v) noexcept
{
for (auto const& t : v)
hash_append(h, t);
}
template <class Hasher, class Key, class Compare, class Alloc>
std::enable_if_t<IsContiguouslyHashable<Key, Hasher>::value>
std::enable_if_t<is_contiguously_hashable<Key, Hasher>::value>
hash_append(Hasher& h, boost::container::flat_set<Key, Compare, Alloc> const& v) noexcept
{
h(&(v.begin()), v.size() * sizeof(Key));
@@ -373,13 +373,13 @@ hash_append(Hasher& h, boost::container::flat_set<Key, Compare, Alloc> const& v)
namespace detail {
inline void
forEachItem(...) noexcept
for_each_item(...) noexcept
{
}
template <class Hasher, class T>
inline int
hashOne(Hasher& h, T const& t) noexcept
hash_one(Hasher& h, T const& t) noexcept
{
hash_append(h, t);
return 0;
@@ -395,7 +395,7 @@ tuple_hash(Hasher& h, std::tuple<T...> const& t, std::index_sequence<I...>) noex
} // namespace detail
template <class Hasher, class... T>
inline std::enable_if_t<!IsContiguouslyHashable<std::tuple<T...>, Hasher>::value>
inline std::enable_if_t<!is_contiguously_hashable<std::tuple<T...>, Hasher>::value>
hash_append(Hasher& h, std::tuple<T...> const& t) noexcept
{
detail::tuple_hash(h, t, std::index_sequence_for<T...>{});

View File

@@ -6,10 +6,10 @@
namespace beast {
// Universal hash function
template <class Hasher = Xxhasher>
struct Uhash
template <class Hasher = xxhasher>
struct uhash
{
Uhash() = default;
uhash() = default;
using result_type = typename Hasher::result_type;

View File

@@ -12,7 +12,7 @@
namespace beast {
class Xxhasher
class xxhasher
{
public:
using result_type = std::size_t;
@@ -21,9 +21,9 @@ private:
static_assert(sizeof(std::size_t) == 8, "requires 64-bit std::size_t");
// Have an internal buffer to avoid the streaming API
// A 64-byte buffer should to be big enough for us
static constexpr std::size_t kINTERNAL_BUFFER_SIZE = 64;
static constexpr std::size_t INTERNAL_BUFFER_SIZE = 64;
alignas(64) std::array<std::uint8_t, kINTERNAL_BUFFER_SIZE> buffer_{};
alignas(64) std::array<std::uint8_t, INTERNAL_BUFFER_SIZE> buffer_{};
std::span<std::uint8_t> readBuffer_;
std::span<std::uint8_t> writeBuffer_;
@@ -102,18 +102,18 @@ private:
}
public:
static constexpr auto const kENDIAN = boost::endian::order::native;
static constexpr auto const endian = boost::endian::order::native;
Xxhasher(Xxhasher const&) = delete;
Xxhasher&
operator=(Xxhasher const&) = delete;
xxhasher(xxhasher const&) = delete;
xxhasher&
operator=(xxhasher const&) = delete;
Xxhasher()
xxhasher()
{
resetBuffers();
}
~Xxhasher() noexcept
~xxhasher() noexcept
{
if (state_ != nullptr)
{
@@ -122,13 +122,13 @@ public:
}
template <class Seed, std::enable_if_t<std::is_unsigned_v<Seed>>* = nullptr>
explicit Xxhasher(Seed seed) : seed_(seed)
explicit xxhasher(Seed seed) : seed_(seed)
{
resetBuffers();
}
template <class Seed, std::enable_if_t<std::is_unsigned_v<Seed>>* = nullptr>
Xxhasher(Seed seed, Seed) : seed_(seed)
xxhasher(Seed seed, Seed) : seed_(seed)
{
resetBuffers();
}

View File

@@ -42,13 +42,13 @@ public:
/** @{ */
template <class Handler>
Hook
makeHook(Handler handler)
make_hook(Handler handler)
{
return makeHook(HookImpl::HandlerType(handler));
return make_hook(HookImpl::HandlerType(handler));
}
virtual Hook
makeHook(HookImpl::HandlerType const& handler) = 0;
make_hook(HookImpl::HandlerType const& handler) = 0;
/** @} */
/** Create a counter with the specified name.
@@ -56,14 +56,14 @@ public:
*/
/** @{ */
virtual Counter
makeCounter(std::string const& name) = 0;
make_counter(std::string const& name) = 0;
Counter
makeCounter(std::string const& prefix, std::string const& name)
make_counter(std::string const& prefix, std::string const& name)
{
if (prefix.empty())
return makeCounter(name);
return makeCounter(prefix + "." + name);
return make_counter(name);
return make_counter(prefix + "." + name);
}
/** @} */
@@ -72,14 +72,14 @@ public:
*/
/** @{ */
virtual Event
makeEvent(std::string const& name) = 0;
make_event(std::string const& name) = 0;
Event
makeEvent(std::string const& prefix, std::string const& name)
make_event(std::string const& prefix, std::string const& name)
{
if (prefix.empty())
return makeEvent(name);
return makeEvent(prefix + "." + name);
return make_event(name);
return make_event(prefix + "." + name);
}
/** @} */
@@ -88,14 +88,14 @@ public:
*/
/** @{ */
virtual Gauge
makeGauge(std::string const& name) = 0;
make_gauge(std::string const& name) = 0;
Gauge
makeGauge(std::string const& prefix, std::string const& name)
make_gauge(std::string const& prefix, std::string const& name)
{
if (prefix.empty())
return makeGauge(name);
return makeGauge(prefix + "." + name);
return make_gauge(name);
return make_gauge(prefix + "." + name);
}
/** @} */
@@ -104,14 +104,14 @@ public:
*/
/** @{ */
virtual Meter
makeMeter(std::string const& name) = 0;
make_meter(std::string const& name) = 0;
Meter
makeMeter(std::string const& prefix, std::string const& name)
make_meter(std::string const& prefix, std::string const& name)
{
if (prefix.empty())
return makeMeter(name);
return makeMeter(prefix + "." + name);
return make_meter(name);
return make_meter(prefix + "." + name);
}
/** @} */
};

View File

@@ -29,7 +29,7 @@ public:
factory function in the Collector interface.
@see Collector.
*/
explicit Counter(std::shared_ptr<CounterImpl> const& impl) : impl_(impl)
explicit Counter(std::shared_ptr<CounterImpl> const& impl) : m_impl(impl)
{
}
@@ -38,8 +38,8 @@ public:
void
increment(value_type amount) const
{
if (impl_)
impl_->increment(amount);
if (m_impl)
m_impl->increment(amount);
}
Counter const&
@@ -85,7 +85,7 @@ public:
}
private:
std::shared_ptr<CounterImpl> impl_;
std::shared_ptr<CounterImpl> m_impl;
};
} // namespace beast::insight

Some files were not shown because too many files have changed in this diff Show More