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
76 T&
77 operator*();
78
82 T*
84 {
85 return &**this;
86 }
87
88private:
89 T t_;
90};
91
92template <class T>
93T&
95{
96 auto lvs = detail::getLocalValues().get();
97 if (lvs == nullptr)
98 {
99 lvs = new detail::LocalValues();
100 lvs->onCoro = false;
101 detail::getLocalValues().reset(lvs);
102 }
103 else
104 {
105 auto const iter = lvs->values.find(this);
106 if (iter != lvs->values.end())
107 return *reinterpret_cast<T*>(iter->second->get());
108 }
109
110 return *reinterpret_cast<T*>(
111 lvs->values.emplace(this, std::make_unique<detail::LocalValues::Value<T>>(t_))
112 .first->second->get());
113}
114} // namespace xrpl
T & operator*()
Stores instance of T specific to the calling coroutine or thread.
Definition LocalValue.h:94
T * operator->()
Stores instance of T specific to the calling coroutine or thread.
Definition LocalValue.h:83
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