rippled
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
8namespace xrpl {
9
10namespace detail {
11
13{
14 explicit LocalValues() = default;
15
16 bool onCoro = true;
17
19 {
20 virtual ~BasicValue() = default;
21 virtual void*
22 get() = 0;
23 };
24
25 template <class T>
27 {
28 T t_;
29
30 Value() = default;
31 explicit Value(T const& t) : t_(t)
32 {
33 }
34
35 void*
36 get() override
37 {
38 return &t_;
39 }
40 };
41
42 // Keys are the address of a LocalValue.
44
45 static inline void
47 {
48 if (lvs && !lvs->onCoro)
49 delete lvs;
50 }
51};
52
53template <class = void>
54boost::thread_specific_ptr<detail::LocalValues>&
56{
57 static boost::thread_specific_ptr<detail::LocalValues> tsp(&detail::LocalValues::cleanup);
58 return tsp;
59}
60
61} // namespace detail
62
63template <class T>
65{
66public:
67 template <class... Args>
68 LocalValue(Args&&... args) : t_(std::forward<Args>(args)...)
69 {
70 }
71
73 T&
74 operator*();
75
77 T*
79 {
80 return &**this;
81 }
82
83private:
84 T t_;
85};
86
87template <class T>
88T&
90{
91 auto lvs = detail::getLocalValues().get();
92 if (!lvs)
93 {
94 lvs = new detail::LocalValues();
95 lvs->onCoro = false;
96 detail::getLocalValues().reset(lvs);
97 }
98 else
99 {
100 auto const iter = lvs->values.find(this);
101 if (iter != lvs->values.end())
102 return *reinterpret_cast<T*>(iter->second->get());
103 }
104
105 return *reinterpret_cast<T*>(
106 lvs->values.emplace(this, std::make_unique<detail::LocalValues::Value<T>>(t_)).first->second->get());
107}
108} // namespace xrpl
T & operator*()
Stores instance of T specific to the calling coroutine or thread.
Definition LocalValue.h:89
T * operator->()
Stores instance of T specific to the calling coroutine or thread.
Definition LocalValue.h:78
LocalValue(Args &&... args)
Definition LocalValue.h:68
T make_unique(T... args)
STL namespace.
boost::thread_specific_ptr< detail::LocalValues > & getLocalValues()
Definition LocalValue.h:55
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:46
std::unordered_map< void const *, std::unique_ptr< BasicValue > > values
Definition LocalValue.h:43