Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F13711454
D11551.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
22 KB
Subscribers
None
D11551.id.diff
View Options
diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp
--- a/src/bitcoind.cpp
+++ b/src/bitcoind.cpp
@@ -19,12 +19,13 @@
#include <node/ui_interface.h>
#include <noui.h>
#include <shutdown.h>
-#include <util/ref.h>
+#include <util/check.h>
#include <util/strencodings.h>
#include <util/system.h>
#include <util/threadnames.h>
#include <util/translation.h>
+#include <any>
#include <functional>
const std::function<std::string(const char *)> G_TRANSLATION_FUN = nullptr;
@@ -49,7 +50,7 @@
RPCServer rpcServer;
NodeContext node;
- util::Ref context{node};
+ std::any context{&node};
HTTPRPCRequestProcessor httpRPCRequestProcessor(config, rpcServer, context);
diff --git a/src/httprpc.h b/src/httprpc.h
--- a/src/httprpc.h
+++ b/src/httprpc.h
@@ -8,11 +8,9 @@
#include <httpserver.h>
#include <rpc/server.h>
-class Config;
+#include <any>
-namespace util {
-class Ref;
-} // namespace util
+class Config;
class HTTPRPCRequestProcessor {
private:
@@ -22,10 +20,10 @@
bool ProcessHTTPRequest(HTTPRequest *request);
public:
- const util::Ref &context;
+ const std::any &context;
HTTPRPCRequestProcessor(Config &configIn, RPCServer &rpcServerIn,
- const util::Ref &contextIn)
+ const std::any &contextIn)
: config(configIn), rpcServer(rpcServerIn), context(contextIn) {}
static bool DelegateHTTPRequest(HTTPRPCRequestProcessor *requestProcessor,
@@ -53,7 +51,7 @@
* Start HTTP REST subsystem.
* Precondition; HTTP and RPC has been started.
*/
-void StartREST(const util::Ref &context);
+void StartREST(const std::any &context);
/** Interrupt RPC REST subsystem */
void InterruptREST();
diff --git a/src/httprpc.cpp b/src/httprpc.cpp
--- a/src/httprpc.cpp
+++ b/src/httprpc.cpp
@@ -8,7 +8,6 @@
#include <config.h>
#include <crypto/hmac_sha256.h>
#include <rpc/protocol.h>
-#include <util/ref.h>
#include <util/strencodings.h>
#include <util/system.h>
#include <util/translation.h>
diff --git a/src/init.h b/src/init.h
--- a/src/init.h
+++ b/src/init.h
@@ -23,10 +23,6 @@
}
class RPCServer;
-namespace util {
-class Ref;
-} // namespace util
-
/** Interrupt threads */
void Interrupt(NodeContext &node);
void Shutdown(NodeContext &node);
diff --git a/src/interfaces/node.cpp b/src/interfaces/node.cpp
--- a/src/interfaces/node.cpp
+++ b/src/interfaces/node.cpp
@@ -28,7 +28,6 @@
#include <sync.h>
#include <txmempool.h>
#include <util/check.h>
-#include <util/ref.h>
#include <util/system.h>
#include <util/translation.h>
#include <validation.h>
@@ -42,6 +41,8 @@
#include <boost/signals2/signal.hpp>
+#include <any>
+
class HTTPRPCRequestProcessor;
namespace interfaces {
namespace {
@@ -334,13 +335,13 @@
void setContext(NodeContext *context) override {
m_context = context;
if (context) {
- m_context_ref.Set(*context);
+ m_context_ref = context;
} else {
- m_context_ref.Clear();
+ m_context_ref.reset();
}
}
NodeContext *m_context{nullptr};
- util::Ref m_context_ref{m_context};
+ std::any m_context_ref{m_context};
};
} // namespace
diff --git a/src/interfaces/wallet.cpp b/src/interfaces/wallet.cpp
--- a/src/interfaces/wallet.cpp
+++ b/src/interfaces/wallet.cpp
@@ -17,7 +17,6 @@
#include <support/allocators/secure.h>
#include <sync.h>
#include <util/check.h>
-#include <util/ref.h>
#include <util/system.h>
#include <util/ui_change_type.h>
#include <wallet/context.h>
@@ -479,7 +478,7 @@
[this, &command](const Config &config,
const JSONRPCRequest &request,
UniValue &result, bool last_handler) {
- return command.actor(config, {request, m_context},
+ return command.actor(config, {request, &m_context},
result, last_handler);
},
command.argNames, command.unique_id);
diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp
--- a/src/qt/bitcoin.cpp
+++ b/src/qt/bitcoin.cpp
@@ -25,7 +25,6 @@
#include <qt/utilitydialog.h>
#include <qt/winshutdownmonitor.h>
#include <uint256.h>
-#include <util/ref.h>
#include <util/system.h>
#include <util/threadnames.h>
#include <util/translation.h>
@@ -49,6 +48,8 @@
#include <boost/signals2/connection.hpp>
+#include <any>
+
#if defined(QT_STATICPLUGIN)
#include <QtPlugin>
#if defined(QT_QPA_PLATFORM_XCB)
@@ -776,7 +777,7 @@
app.setNode(*node);
RPCServer rpcServer;
- util::Ref context{node_context};
+ std::any context{&node_context};
HTTPRPCRequestProcessor httpRPCRequestProcessor(config, rpcServer, context);
try {
diff --git a/src/qt/test/apptests.cpp b/src/qt/test/apptests.cpp
--- a/src/qt/test/apptests.cpp
+++ b/src/qt/test/apptests.cpp
@@ -14,7 +14,6 @@
#include <qt/rpcconsole.h>
#include <rpc/server.h>
#include <shutdown.h>
-#include <util/ref.h>
#include <validation.h>
#if defined(HAVE_CONFIG_H)
@@ -35,6 +34,8 @@
#include <QtTest/QtTestGui>
#include <QtTest/QtTestWidgets>
+#include <any>
+
namespace {
//! Call getblockchaininfo RPC and check first field of JSON output.
void TestRpcCommand(RPCConsole *console) {
@@ -95,7 +96,7 @@
m_app.baseInitialize(config);
RPCServer rpcServer;
- util::Ref context;
+ std::any context;
HTTPRPCRequestProcessor httpRPCRequestProcessor(config, rpcServer, context);
m_app.requestInitialize(config, rpcServer, httpRPCRequestProcessor);
m_app.exec();
diff --git a/src/rest.cpp b/src/rest.cpp
--- a/src/rest.cpp
+++ b/src/rest.cpp
@@ -20,7 +20,7 @@
#include <streams.h>
#include <sync.h>
#include <txmempool.h>
-#include <util/ref.h>
+#include <util/system.h>
#include <validation.h>
#include <version.h>
@@ -28,6 +28,8 @@
#include <univalue.h>
+#include <any>
+
// Allow a max of 15 outpoints to be queried at once.
static const size_t MAX_GETUTXOS_OUTPOINTS = 15;
@@ -76,10 +78,9 @@
* context is not found.
* @returns Pointer to the node context or nullptr if not found.
*/
-static NodeContext *GetNodeContext(const util::Ref &context, HTTPRequest *req) {
- NodeContext *node =
- context.Has<NodeContext>() ? &context.Get<NodeContext>() : nullptr;
- if (!node) {
+static NodeContext *GetNodeContext(const std::any &context, HTTPRequest *req) {
+ auto node_context = util::AnyPtr<NodeContext>(context);
+ if (!node_context) {
RESTERR(req, HTTP_INTERNAL_SERVER_ERROR,
strprintf("%s:%d (%s)\n"
"Internal bug detected: Node context not found!\n"
@@ -87,7 +88,7 @@
__FILE__, __LINE__, __func__, PACKAGE_BUGREPORT));
return nullptr;
}
- return node;
+ return node_context;
}
/**
@@ -97,14 +98,13 @@
* context mempool is not found.
* @returns Pointer to the mempool or nullptr if no mempool found.
*/
-static CTxMemPool *GetMemPool(const util::Ref &context, HTTPRequest *req) {
- NodeContext *node =
- context.Has<NodeContext>() ? &context.Get<NodeContext>() : nullptr;
- if (!node || !node->mempool) {
+static CTxMemPool *GetMemPool(const std::any &context, HTTPRequest *req) {
+ auto node_context = util::AnyPtr<NodeContext>(context);
+ if (!node_context || !node_context->mempool) {
RESTERR(req, HTTP_NOT_FOUND, "Mempool disabled or instance not found");
return nullptr;
}
- return node->mempool.get();
+ return node_context->mempool.get();
}
static RetFormat ParseDataFormat(std::string ¶m,
@@ -156,7 +156,7 @@
return true;
}
-static bool rest_headers(Config &config, const util::Ref &context,
+static bool rest_headers(Config &config, const std::any &context,
HTTPRequest *req, const std::string &strURIPart) {
if (!CheckWarmup(req)) {
return false;
@@ -322,19 +322,19 @@
}
}
-static bool rest_block_extended(Config &config, const util::Ref &context,
+static bool rest_block_extended(Config &config, const std::any &context,
HTTPRequest *req,
const std::string &strURIPart) {
return rest_block(config, req, strURIPart, true);
}
-static bool rest_block_notxdetails(Config &config, const util::Ref &context,
+static bool rest_block_notxdetails(Config &config, const std::any &context,
HTTPRequest *req,
const std::string &strURIPart) {
return rest_block(config, req, strURIPart, false);
}
-static bool rest_chaininfo(Config &config, const util::Ref &context,
+static bool rest_chaininfo(Config &config, const std::any &context,
HTTPRequest *req, const std::string &strURIPart) {
if (!CheckWarmup(req)) {
return false;
@@ -361,7 +361,7 @@
}
}
-static bool rest_mempool_info(Config &config, const util::Ref &context,
+static bool rest_mempool_info(Config &config, const std::any &context,
HTTPRequest *req, const std::string &strURIPart) {
if (!CheckWarmup(req)) {
return false;
@@ -391,7 +391,7 @@
}
}
-static bool rest_mempool_contents(Config &config, const util::Ref &context,
+static bool rest_mempool_contents(Config &config, const std::any &context,
HTTPRequest *req,
const std::string &strURIPart) {
if (!CheckWarmup(req)) {
@@ -422,7 +422,7 @@
}
}
-static bool rest_tx(Config &config, const util::Ref &context, HTTPRequest *req,
+static bool rest_tx(Config &config, const std::any &context, HTTPRequest *req,
const std::string &strURIPart) {
if (!CheckWarmup(req)) {
return false;
@@ -494,7 +494,7 @@
}
}
-static bool rest_getutxos(Config &config, const util::Ref &context,
+static bool rest_getutxos(Config &config, const std::any &context,
HTTPRequest *req, const std::string &strURIPart) {
if (!CheckWarmup(req)) {
return false;
@@ -717,7 +717,7 @@
}
}
-static bool rest_blockhash_by_height(Config &config, const util::Ref &context,
+static bool rest_blockhash_by_height(Config &config, const std::any &context,
HTTPRequest *req,
const std::string &str_uri_part) {
if (!CheckWarmup(req)) {
@@ -771,7 +771,7 @@
static const struct {
const char *prefix;
- bool (*handler)(Config &config, const util::Ref &context, HTTPRequest *req,
+ bool (*handler)(Config &config, const std::any &context, HTTPRequest *req,
const std::string &strReq);
} uri_prefixes[] = {
{"/rest/tx/", rest_tx},
@@ -785,7 +785,7 @@
{"/rest/blockhashbyheight/", rest_blockhash_by_height},
};
-void StartREST(const util::Ref &context) {
+void StartREST(const std::any &context) {
for (const auto &up : uri_prefixes) {
auto handler = [&context, up](Config &config, HTTPRequest *req,
const std::string &prefix) {
diff --git a/src/rpc/blockchain.h b/src/rpc/blockchain.h
--- a/src/rpc/blockchain.h
+++ b/src/rpc/blockchain.h
@@ -10,6 +10,8 @@
#include <univalue.h>
+#include <any>
+
class CBlock;
class CBlockIndex;
class CChainState;
@@ -17,9 +19,6 @@
class CTxMemPool;
class RPCHelpMan;
struct NodeContext;
-namespace util {
-class Ref;
-} // namespace util
extern RecursiveMutex cs_main;
@@ -53,9 +52,9 @@
const CBlockIndex *blockindex)
LOCKS_EXCLUDED(cs_main);
-NodeContext &EnsureNodeContext(const util::Ref &context);
-CTxMemPool &EnsureMemPool(const util::Ref &context);
-ChainstateManager &EnsureChainman(const util::Ref &context);
+NodeContext &EnsureNodeContext(const std::any &context);
+CTxMemPool &EnsureMemPool(const std::any &context);
+ChainstateManager &EnsureChainman(const std::any &context);
/**
* Helper to create UTXO snapshots given a chainstate and a file handle.
diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp
--- a/src/rpc/blockchain.cpp
+++ b/src/rpc/blockchain.cpp
@@ -30,7 +30,6 @@
#include <txdb.h>
#include <txmempool.h>
#include <undo.h>
-#include <util/ref.h>
#include <util/strencodings.h>
#include <util/system.h>
#include <util/translation.h>
@@ -53,14 +52,15 @@
static std::condition_variable cond_blockchange;
static CUpdatedBlock latestblock GUARDED_BY(cs_blockchange);
-NodeContext &EnsureNodeContext(const util::Ref &context) {
- if (!context.Has<NodeContext>()) {
+NodeContext &EnsureNodeContext(const std::any &context) {
+ auto node_context = util::AnyPtr<NodeContext>(context);
+ if (!node_context) {
throw JSONRPCError(RPC_INTERNAL_ERROR, "Node context not found");
}
- return context.Get<NodeContext>();
+ return *node_context;
}
-CTxMemPool &EnsureMemPool(const util::Ref &context) {
+CTxMemPool &EnsureMemPool(const std::any &context) {
const NodeContext &node = EnsureNodeContext(context);
if (!node.mempool) {
throw JSONRPCError(RPC_CLIENT_MEMPOOL_DISABLED,
@@ -69,7 +69,7 @@
return *node.mempool;
}
-ChainstateManager &EnsureChainman(const util::Ref &context) {
+ChainstateManager &EnsureChainman(const std::any &context) {
const NodeContext &node = EnsureNodeContext(context);
if (!node.chainman) {
throw JSONRPCError(RPC_INTERNAL_ERROR, "Node chainman not found");
diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp
--- a/src/rpc/misc.cpp
+++ b/src/rpc/misc.cpp
@@ -21,7 +21,6 @@
#include <script/descriptor.h>
#include <util/check.h>
#include <util/message.h> // For MessageSign(), MessageVerify()
-#include <util/ref.h>
#include <util/strencodings.h>
#include <util/system.h>
@@ -472,9 +471,9 @@
"Timestamp must be 0 or greater");
}
SetMockTime(time);
- if (request.context.Has<NodeContext>()) {
- for (const auto &chain_client :
- request.context.Get<NodeContext>().chain_clients) {
+ auto node_context = util::AnyPtr<NodeContext>(request.context);
+ if (node_context) {
+ for (const auto &chain_client : node_context->chain_clients) {
chain_client->setMockTime(time);
}
}
@@ -509,11 +508,12 @@
"delta_time must be between 1 and 3600 seconds (1 hr)");
}
+ auto node_context = util::AnyPtr<NodeContext>(request.context);
// protect against null pointer dereference
- CHECK_NONFATAL(request.context.Has<NodeContext>());
- NodeContext &node = request.context.Get<NodeContext>();
- CHECK_NONFATAL(node.scheduler);
- node.scheduler->MockForward(std::chrono::seconds(delta_seconds));
+ CHECK_NONFATAL(node_context);
+ CHECK_NONFATAL(node_context->scheduler);
+ node_context->scheduler->MockForward(
+ std::chrono::seconds(delta_seconds));
return NullUniValue;
},
diff --git a/src/rpc/request.h b/src/rpc/request.h
--- a/src/rpc/request.h
+++ b/src/rpc/request.h
@@ -5,13 +5,10 @@
#ifndef BITCOIN_RPC_REQUEST_H
#define BITCOIN_RPC_REQUEST_H
-#include <string>
-
#include <univalue.h>
-namespace util {
-class Ref;
-} // namespace util
+#include <any>
+#include <string>
UniValue JSONRPCRequestObj(const std::string &strMethod, const UniValue ¶ms,
const UniValue &id);
@@ -39,15 +36,15 @@
std::string URI;
std::string authUser;
std::string peerAddr;
- const util::Ref &context;
+ const std::any &context;
- explicit JSONRPCRequest(const util::Ref &contextIn)
+ explicit JSONRPCRequest(const std::any &contextIn)
: id(NullUniValue), params(NullUniValue), context(contextIn) {}
//! Initializes request information from another request object and the
//! given context. The implementation should be updated if any members are
//! added or removed above.
- JSONRPCRequest(const JSONRPCRequest &other, const util::Ref &contextIn)
+ JSONRPCRequest(const JSONRPCRequest &other, const std::any &contextIn)
: id(other.id), strMethod(other.strMethod), params(other.params),
mode(other.mode), URI(other.URI), authUser(other.authUser),
peerAddr(other.peerAddr), context(contextIn) {}
diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp
--- a/src/rpc/server.cpp
+++ b/src/rpc/server.cpp
@@ -127,7 +127,7 @@
}
sort(vCommands.begin(), vCommands.end());
- JSONRPCRequest jreq(helpreq);
+ JSONRPCRequest jreq = helpreq;
jreq.mode = JSONRPCRequest::GET_HELP;
jreq.params = UniValue();
@@ -551,7 +551,7 @@
UniValue CRPCTable::dumpArgMap(const Config &config,
const JSONRPCRequest &args_request) const {
- JSONRPCRequest request(args_request);
+ JSONRPCRequest request = args_request;
request.mode = JSONRPCRequest::GET_ARGS;
UniValue ret{UniValue::VARR};
diff --git a/src/test/rpc_server_tests.cpp b/src/test/rpc_server_tests.cpp
--- a/src/test/rpc_server_tests.cpp
+++ b/src/test/rpc_server_tests.cpp
@@ -8,13 +8,13 @@
#include <chainparams.h>
#include <config.h>
-#include <util/ref.h>
#include <util/system.h>
#include <test/util/setup_common.h>
#include <boost/test/unit_test.hpp>
+#include <any>
#include <string>
BOOST_FIXTURE_TEST_SUITE(rpc_server_tests, TestingSetup)
@@ -48,7 +48,7 @@
args.pushKV("arg1", "value1");
// Registered commands execute and return values correctly
- util::Ref context{m_node};
+ std::any context{&m_node};
JSONRPCRequest request(context);
request.strMethod = commandName;
request.params = args;
@@ -88,7 +88,7 @@
args.pushKV("arg2", "value2");
// Registered commands execute and return values correctly
- util::Ref context{m_node};
+ std::any context{&m_node};
JSONRPCRequest request(context);
request.strMethod = commandName;
request.params = args;
diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp
--- a/src/test/rpc_tests.cpp
+++ b/src/test/rpc_tests.cpp
@@ -11,7 +11,6 @@
#include <core_io.h>
#include <interfaces/chain.h>
#include <node/context.h>
-#include <util/ref.h>
#include <util/time.h>
#include <test/util/setup_common.h>
@@ -21,7 +20,9 @@
#include <univalue.h>
-UniValue CallRPC(const std::string &args, const util::Ref &context) {
+#include <any>
+
+UniValue CallRPC(const std::string &args, const std::any &context) {
std::vector<std::string> vArgs;
boost::split(vArgs, args, boost::is_any_of(" \t"));
std::string strMethod = vArgs[0];
@@ -44,7 +45,7 @@
class RPCTestingSetup : public TestingSetup {
public:
UniValue CallRPC(const std::string &args) {
- const util::Ref context{m_node};
+ const std::any context{&m_node};
return ::CallRPC(args, context);
}
};
diff --git a/src/util/system.h b/src/util/system.h
--- a/src/util/system.h
+++ b/src/util/system.h
@@ -25,6 +25,7 @@
#include <util/threadnames.h>
#include <util/time.h>
+#include <any>
#include <cstdint>
#include <exception>
#include <map>
@@ -498,6 +499,16 @@
dst.insert(src.begin(), src.end());
}
+/**
+ * Helper function to access the contained object of a std::any instance.
+ * Returns a pointer to the object if passed instance has a value and the type
+ * matches, nullptr otherwise.
+ */
+template <typename T> T *AnyPtr(const std::any &any) noexcept {
+ T *const *ptr = std::any_cast<T *>(&any);
+ return ptr ? *ptr : nullptr;
+}
+
#ifdef WIN32
class WinCmdLineArgs {
public:
diff --git a/src/wallet/rpcwallet.h b/src/wallet/rpcwallet.h
--- a/src/wallet/rpcwallet.h
+++ b/src/wallet/rpcwallet.h
@@ -8,6 +8,7 @@
#include <script/sighashtype.h>
#include <span.h>
+#include <any>
#include <memory>
#include <string>
#include <vector>
@@ -21,10 +22,6 @@
class RPCHelpMan;
struct WalletContext;
-namespace util {
-class Ref;
-}
-
Span<const CRPCCommand> GetWalletRPCCommands();
/**
@@ -37,7 +34,7 @@
GetWalletForJSONRPCRequest(const JSONRPCRequest &request);
void EnsureWalletIsUnlocked(const CWallet *);
-WalletContext &EnsureWalletContext(const util::Ref &context);
+WalletContext &EnsureWalletContext(const std::any &context);
LegacyScriptPubKeyMan &EnsureLegacyScriptPubKeyMan(CWallet &wallet,
bool also_create = false);
diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp
--- a/src/wallet/rpcwallet.cpp
+++ b/src/wallet/rpcwallet.cpp
@@ -24,7 +24,6 @@
#include <util/error.h>
#include <util/message.h> // For MessageSign()
#include <util/moneystr.h>
-#include <util/ref.h>
#include <util/string.h>
#include <util/system.h>
#include <util/translation.h>
@@ -143,11 +142,12 @@
}
}
-WalletContext &EnsureWalletContext(const util::Ref &context) {
- if (!context.Has<WalletContext>()) {
+WalletContext &EnsureWalletContext(const std::any &context) {
+ auto wallet_context = util::AnyPtr<WalletContext>(context);
+ if (!wallet_context) {
throw JSONRPCError(RPC_INTERNAL_ERROR, "Wallet context not found");
}
- return context.Get<WalletContext>();
+ return *wallet_context;
}
// also_create should only be set to true only when the RPC is expected to add
diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp
--- a/src/wallet/test/wallet_tests.cpp
+++ b/src/wallet/test/wallet_tests.cpp
@@ -9,7 +9,6 @@
#include <node/context.h>
#include <policy/policy.h>
#include <rpc/server.h>
-#include <util/ref.h>
#include <util/translation.h>
#include <validation.h>
#include <wallet/coincontrol.h>
@@ -24,6 +23,7 @@
#include <univalue.h>
+#include <any>
#include <cstdint>
#include <future>
#include <memory>
@@ -229,7 +229,7 @@
newTip->GetBlockTimeMax() + TIMESTAMP_WINDOW + 1);
key.pushKV("internal", UniValue(true));
keys.push_back(key);
- util::Ref context;
+ std::any context;
JSONRPCRequest request(context);
request.params.setArray();
request.params.push_back(keys);
@@ -298,7 +298,7 @@
::ChainActive().Height(),
::ChainActive().Tip()->GetBlockHash());
}
- util::Ref context;
+ std::any context;
JSONRPCRequest request(context);
request.params.setArray();
request.params.push_back(backup_file);
@@ -314,7 +314,7 @@
LOCK(wallet->cs_wallet);
wallet->SetupLegacyScriptPubKeyMan();
- util::Ref context;
+ std::any context;
JSONRPCRequest request(context);
request.params.setArray();
request.params.push_back(backup_file);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Apr 26, 12:06 (2 h, 47 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5573507
Default Alt Text
D11551.id.diff (22 KB)
Attached To
D11551: refactor: replace util::Ref with std::any (C++17)
Event Timeline
Log In to Comment