-
Notifications
You must be signed in to change notification settings - Fork 2
/
lazy_tuple.h
79 lines (63 loc) · 1.27 KB
/
lazy_tuple.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#pragma once
#include <unordered_map>
#include <memory>
#include <iostream>
namespace
{
template <typename T>
std::uintptr_t get_unique_type_id()
{
static const int placeholder;
return reinterpret_cast<std::uintptr_t>(&placeholder);
}
struct base_type {};
template <typename T>
struct derived_type : public base_type
{
T value;
};
}
namespace ay
{
class lazy_tuple;
}
namespace std
{
template <typename T>
T& get(ay::lazy_tuple& container);
}
namespace ay
{
class lazy_tuple
{
public:
template <typename T>
friend T& std::get(lazy_tuple&);
/* TODO
lazy_tuple<T...>(T...)
lazy_tuple<T...>(std::tuple<T...>)
insert<T>(T&&)
emplace<T...>(T&&...)
contains<T>()
get<T>()
size()
empty()
clear()
swap(lazy_tuple&)
merge(lazy_tuple&)
*/
private:
std::unordered_map<std::uintptr_t, std::unique_ptr<base_type>> m_storage;
};
}
template <typename T>
T& std::get(ay::lazy_tuple& tuple)
{
auto id = get_unique_type_id<T>();
auto found = tuple.m_storage.find(id);
if (found == tuple.m_storage.end())
{
found = tuple.m_storage.try_emplace(id, std::make_unique<derived_type<T>>()).first;
}
return static_cast<derived_type<T>*>(found->second.get())->value;
}