Files
rippled/include/xrpl/basics/LocalValue.h
yinyiqian1 1e73f3f3ff Merge develop into ConfidentialTransfer (#6987)
Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: chuanshanjida <chuanshanjida@outlook.com>
Co-authored-by: Ed Hennis <ed@ripple.com>
Co-authored-by: Bart <bthomee@users.noreply.github.com>
Co-authored-by: Bart <11445373+bthomee@users.noreply.github.com>
Co-authored-by: Zhiyuan Wang <96991820+Kassaking7@users.noreply.github.com>
Co-authored-by: Alex Kremer <akremer@ripple.com>
Co-authored-by: Ayaz Salikhov <mathbunnyru@users.noreply.github.com>
Co-authored-by: Sergey Kuznetsov <skuznetsov@ripple.com>
Co-authored-by: JCW <a1q123456@users.noreply.github.com>
Co-authored-by: xrplf-ai-reviewer[bot] <266832837+xrplf-ai-reviewer[bot]@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Gregory Tsipenyuk <gregtatcam@users.noreply.github.com>
Co-authored-by: chuanshanjida <chuanshanjida@outlook.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Vito Tumas <5780819+Tapanito@users.noreply.github.com>
2026-04-22 23:34:03 -04:00

111 lines
2.1 KiB
C++

#pragma once
#include <boost/thread/tss.hpp>
#include <memory>
#include <unordered_map>
#include <utility>
namespace xrpl {
namespace detail {
struct LocalValues
{
explicit LocalValues() = default;
bool onCoro = true;
struct BasicValue
{
virtual ~BasicValue() = default;
virtual void*
get() = 0;
};
template <class T>
struct Value : BasicValue
{
T t_;
Value() = default;
explicit Value(T t) : t_(std::move(t))
{
}
void*
get() override
{
return &t_;
}
};
// Keys are the address of a LocalValue.
std::unordered_map<void const*, std::unique_ptr<BasicValue>> values;
static void
cleanup(LocalValues* lvs)
{
if ((lvs != nullptr) && !lvs->onCoro)
delete lvs;
}
};
template <class = void>
boost::thread_specific_ptr<detail::LocalValues>&
getLocalValues()
{
static boost::thread_specific_ptr<detail::LocalValues> tsp(&detail::LocalValues::cleanup);
return tsp;
}
} // namespace detail
template <class T>
class LocalValue
{
public:
template <class... Args>
LocalValue(Args&&... args) : t_(std::forward<Args>(args)...)
{
}
/** Stores instance of T specific to the calling coroutine or thread. */
T&
operator*();
/** Stores instance of T specific to the calling coroutine or thread. */
T*
operator->()
{
return &**this;
}
private:
T t_;
};
template <class T>
T&
LocalValue<T>::operator*()
{
auto lvs = detail::getLocalValues().get();
if (lvs == nullptr)
{
lvs = new detail::LocalValues();
lvs->onCoro = false;
detail::getLocalValues().reset(lvs);
}
else
{
auto const iter = lvs->values.find(this);
if (iter != lvs->values.end())
return *reinterpret_cast<T*>(iter->second->get());
}
return *reinterpret_cast<T*>(
lvs->values.emplace(this, std::make_unique<detail::LocalValues::Value<T>>(t_))
.first->second->get());
}
} // namespace xrpl