aboutsummaryrefslogtreecommitdiffstats
path: root/library/cpp/yt/misc/variant-inl.h
diff options
context:
space:
mode:
authorDevtools Arcadia <arcadia-devtools@yandex-team.ru>2022-02-07 18:08:42 +0300
committerDevtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net>2022-02-07 18:08:42 +0300
commit1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch)
treee26c9fed0de5d9873cce7e00bc214573dc2195b7 /library/cpp/yt/misc/variant-inl.h
downloadydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'library/cpp/yt/misc/variant-inl.h')
-rw-r--r--library/cpp/yt/misc/variant-inl.h70
1 files changed, 70 insertions, 0 deletions
diff --git a/library/cpp/yt/misc/variant-inl.h b/library/cpp/yt/misc/variant-inl.h
new file mode 100644
index 0000000000..fb7d98d4be
--- /dev/null
+++ b/library/cpp/yt/misc/variant-inl.h
@@ -0,0 +1,70 @@
+#ifndef VARIANT_INL_H_
+#error "Direct inclusion of this file is not allowed, include variant.h"
+// For the sake of sane code completion.
+#include "variant.h"
+#endif
+
+#include <type_traits>
+
+namespace NYT {
+
+////////////////////////////////////////////////////////////////////////////////
+
+namespace NDetail {
+
+template <class T>
+struct TIndexOf<T>
+{
+ static constexpr size_t Value = std::numeric_limits<size_t>::max();
+};
+
+template <class T, class T0, class... Ts>
+struct TIndexOf<T, T0, Ts...>
+{
+ static constexpr size_t Value = std::is_same_v<T, T0>
+ ? 0
+ : 1 + TIndexOf<T, Ts...>::Value;
+};
+
+template <size_t Index, class... Ts>
+struct TVariantFormatter;
+
+template <size_t Index>
+struct TVariantFormatter<Index>
+{
+ template <class TVariant>
+ static void Do(TStringBuilderBase* /*builder*/, const TVariant& /*variant*/, TStringBuf /*spec*/)
+ { }
+};
+
+template <size_t Index, class T, class... Ts>
+struct TVariantFormatter<Index, T, Ts...>
+{
+ template <class TVariant>
+ static void Do(TStringBuilderBase* builder, const TVariant& variant, TStringBuf spec)
+ {
+ if (variant.index() == Index) {
+ FormatValue(builder, std::get<Index>(variant), spec);
+ } else {
+ TVariantFormatter<Index + 1, Ts...>::Do(builder, variant, spec);
+ }
+ }
+};
+
+} // namespace NDetail
+
+template <class... Ts>
+void FormatValue(TStringBuilderBase* builder, const std::variant<Ts...>& variant, TStringBuf spec)
+{
+ NDetail::TVariantFormatter<0, Ts...>::Do(builder, variant, spec);
+}
+
+template <class... Ts>
+TString ToString(const std::variant<Ts...>& variant)
+{
+ return ToStringViaBuilder(variant);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT