Skip to content

Commit 438f4c3

Browse files
committed
add TaggedVariant
1 parent f2f7df1 commit 438f4c3

File tree

2 files changed

+100
-0
lines changed

2 files changed

+100
-0
lines changed

include/gf2/core/TaggedVariant.h

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
// SPDX-License-Identifier: Zlib
2+
// Copyright (c) 2023 Julien Bernard
3+
#ifndef GF_TAGGED_VARIANT_H
4+
#define GF_TAGGED_VARIANT_H
5+
6+
#include <variant>
7+
8+
#include "TypeTraits.h"
9+
10+
namespace gf {
11+
12+
template<typename Enum, typename ... Args>
13+
class TaggedVariant {
14+
public:
15+
TaggedVariant() = default;
16+
17+
template<typename T, typename = PreventHiddenCopyMove<T, TaggedVariant>>
18+
constexpr TaggedVariant(T&& data)
19+
: m_data(std::forward<T>(data))
20+
{
21+
}
22+
23+
Enum type() const
24+
{
25+
return static_cast<Enum>(m_data.index());
26+
}
27+
28+
template<typename T>
29+
constexpr bool is() const
30+
{
31+
return std::holds_alternative<T>(m_data);
32+
}
33+
34+
template<typename T>
35+
constexpr T& get()
36+
{
37+
return std::get<T>(m_data);
38+
}
39+
40+
template<typename T>
41+
constexpr const T& get() const
42+
{
43+
return std::get<T>(m_data);
44+
}
45+
46+
template<Enum E>
47+
constexpr auto& from()
48+
{
49+
return std::get<static_cast<std::size_t>(E)>(m_data);
50+
}
51+
52+
template<Enum E>
53+
constexpr const auto& from() const
54+
{
55+
return std::get<static_cast<std::size_t>(E)>(m_data);
56+
}
57+
58+
constexpr auto& raw()
59+
{
60+
return m_data;
61+
}
62+
63+
constexpr const auto& raw() const
64+
{
65+
return m_data;
66+
}
67+
68+
private:
69+
std::variant<std::monostate, Args...> m_data;
70+
};
71+
72+
namespace details {
73+
74+
template<typename Archive, typename Self>
75+
Archive& handle_tagged_variant_serialization(Archive& ar, Self& self)
76+
{
77+
return ar | self.raw();
78+
}
79+
80+
}
81+
82+
template<typename Archive, typename Enum, typename ... Args>
83+
inline Archive& operator|(Archive& ar, TaggedVariant<Enum, Args...>& variant)
84+
{
85+
return details::handle_tagged_variant_serialization(ar, variant);
86+
}
87+
88+
template<typename Archive, typename Enum, typename ... Args>
89+
inline Archive& operator|(Archive& ar, const TaggedVariant<Enum, Args...>& variant)
90+
{
91+
return details::handle_tagged_variant_serialization(ar, variant);
92+
}
93+
94+
}
95+
96+
#endif // GF_TAGGED_VARIANT_H

library/core/TaggedVariant.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// SPDX-License-Identifier: Zlib
2+
// Copyright (c) 2023 Julien Bernard
3+
4+
#include <gf2/core/TaggedVariant.h>

0 commit comments

Comments
 (0)