xrpld
Loading...
Searching...
No Matches
LocalValue.h
1#pragma once
2
3#include <boost/thread/tss.hpp>
4
5#include <memory>
6#include <unordered_map>
7#include <utility>
8
9namespace xrpl {
10
11namespace detail {
12
14{
15 explicit LocalValues() = default;
16
17 bool onCoro = true;
18
20 {
21 virtual ~BasicValue() = default;
22 virtual void*
23 get() = 0;
24 };
25
26 template <class T>
28 {
29 T t;
30
31 Value() = default;
32 explicit Value(T t) : t(std::move(t))
33 {
34 }
35
36 void*
37 get() override
38 {
39 return &t;
40 }
41 };
42
43 // Keys are the address of a LocalValue.
45
46 static void
48 {
49 if ((lvs != nullptr) && !lvs->onCoro)
50 delete lvs;
51 }
52};
53
54template <class = void>
55boost::thread_specific_ptr<detail::LocalValues>&
57{
58 static boost::thread_specific_ptr<detail::LocalValues> kTsp(&detail::LocalValues::cleanup);
59 return kTsp;
60}
61
62} // namespace detail
63
64template <class T>
66{
67public:
68 template <class... Args>
69 LocalValue(Args&&... args) : t_(std::forward<Args>(args)...)
70 {
71 }
72
74 T&
75 operator*();
76
78 T*
80 {
81 return &**this;
82 }
83
84private:
85 T t_;
86};
87
88template <class T>
89T&
91{
92 auto lvs = detail::getLocalValues().get();
93 if (lvs == nullptr)
94 {
95 lvs = new detail::LocalValues();
96 lvs->onCoro = false;
97 detail::getLocalValues().reset(lvs);
98 }
99 else
100 {
101 auto const iter = lvs->values.find(this);
102 if (iter != lvs->values.end())
103 return *reinterpret_cast<T*>(iter->second->get());
104 }
105
106 return *reinterpret_cast<T*>(
107 lvs->values.emplace(this, std::make_unique<detail::LocalValues::Value<T>>(t_))
108 .first->second->get());
109}
110} // namespace xrpl
T & operator*()
Stores instance of T specific to the calling coroutine or thread.
Definition LocalValue.h:90
T * operator->()
Stores instance of T specific to the calling coroutine or thread.
Definition LocalValue.h:79
LocalValue(Args &&... args)
Definition LocalValue.h:69
T make_unique(T... args)
STL namespace.
boost::thread_specific_ptr< detail::LocalValues > & getLocalValues()
Definition LocalValue.h:56
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
static void cleanup(LocalValues *lvs)
Definition LocalValue.h:47
std::unordered_map< void const *, std::unique_ptr< BasicValue > > values
Definition LocalValue.h:44