mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-26 09:31:59 +00:00
Reader reflection of std::variant<Ts...>
This commit is contained in:
parent
b2672c6009
commit
27ddce4cd6
@ -7,29 +7,6 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
void Reflect(Reader& visitor, std::variant<std::monostate, int>& version) {
|
|
||||||
if (visitor.IsNull()) {
|
|
||||||
visitor.GetNull();
|
|
||||||
version = std::monostate();
|
|
||||||
} else
|
|
||||||
version = visitor.GetInt();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Reflect(Reader& visitor, lsRequestId& id) {
|
|
||||||
if (visitor.IsNull()) {
|
|
||||||
visitor.GetNull();
|
|
||||||
id = std::monostate();
|
|
||||||
} else if (visitor.IsString()) {
|
|
||||||
std::string v;
|
|
||||||
Reflect(visitor, v);
|
|
||||||
id = v;
|
|
||||||
} else {
|
|
||||||
int64_t v;
|
|
||||||
Reflect(visitor, v);
|
|
||||||
id = v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MessageRegistry* MessageRegistry::instance_ = nullptr;
|
MessageRegistry* MessageRegistry::instance_ = nullptr;
|
||||||
|
|
||||||
lsTextDocumentIdentifier
|
lsTextDocumentIdentifier
|
||||||
|
@ -24,7 +24,6 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
using lsRequestId = std::variant<std::monostate, int64_t, std::string>;
|
using lsRequestId = std::variant<std::monostate, int64_t, std::string>;
|
||||||
void Reflect(Reader& visitor, lsRequestId& id);
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
@ -253,7 +252,6 @@ struct lsTextDocumentIdentifier {
|
|||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(lsTextDocumentIdentifier, uri);
|
MAKE_REFLECT_STRUCT(lsTextDocumentIdentifier, uri);
|
||||||
|
|
||||||
void Reflect(Reader& visitor, std::variant<std::monostate, int>& version);
|
|
||||||
struct lsVersionedTextDocumentIdentifier {
|
struct lsVersionedTextDocumentIdentifier {
|
||||||
lsDocumentUri uri;
|
lsDocumentUri uri;
|
||||||
// The version number of this document. number | null
|
// The version number of this document. number | null
|
||||||
|
@ -532,4 +532,4 @@ void EmitDiagnostics(WorkingFiles* working_files,
|
|||||||
if (working_file)
|
if (working_file)
|
||||||
working_file->diagnostics_ = diagnostics;
|
working_file->diagnostics_ = diagnostics;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,10 @@
|
|||||||
#include <optional.h>
|
#include <optional.h>
|
||||||
#include <variant.h>
|
#include <variant.h>
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <type_traits>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
enum class SerializeFormat { Json, MessagePack };
|
enum class SerializeFormat { Json, MessagePack };
|
||||||
@ -19,7 +21,7 @@ class Reader {
|
|||||||
virtual bool IsNull() = 0;
|
virtual bool IsNull() = 0;
|
||||||
virtual bool IsArray() = 0;
|
virtual bool IsArray() = 0;
|
||||||
virtual bool IsInt() = 0;
|
virtual bool IsInt() = 0;
|
||||||
// virtual bool IsInt64() = 0;
|
virtual bool IsInt64() = 0;
|
||||||
// virtual bool IsUint64() = 0;
|
// virtual bool IsUint64() = 0;
|
||||||
virtual bool IsString() = 0;
|
virtual bool IsString() = 0;
|
||||||
|
|
||||||
@ -187,8 +189,44 @@ void Reflect(Writer& visitor, optional<T>& value) {
|
|||||||
visitor.Null();
|
visitor.Null();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
template <typename B0, typename... Bs>
|
||||||
|
struct disjunction
|
||||||
|
: std::conditional<bool(B0::value), B0, disjunction<Bs...>>::type {};
|
||||||
|
template <typename B0>
|
||||||
|
struct disjunction<B0> : B0 {};
|
||||||
|
}
|
||||||
|
|
||||||
template <size_t N, typename... Ts>
|
template <size_t N, typename... Ts>
|
||||||
struct ReflectVariant {
|
struct ReflectVariant {
|
||||||
|
template <typename T>
|
||||||
|
typename std::enable_if<disjunction<std::is_same<T, Ts>...>::value,
|
||||||
|
void>::type
|
||||||
|
ReflectTag(Reader& visitor, std::variant<Ts...>& value) {
|
||||||
|
T a;
|
||||||
|
Reflect(visitor, a);
|
||||||
|
value = a;
|
||||||
|
}
|
||||||
|
template <typename T>
|
||||||
|
typename std::enable_if<!disjunction<std::is_same<T, Ts>...>::value,
|
||||||
|
void>::type
|
||||||
|
ReflectTag(Reader&, std::variant<Ts...>&) {}
|
||||||
|
|
||||||
|
void operator()(Reader& visitor, std::variant<Ts...>& value) {
|
||||||
|
if (visitor.IsNull())
|
||||||
|
ReflectTag<std::monostate>(visitor, value);
|
||||||
|
// It is possible that IsInt64() && IsInt(). We don't call ReflectTag<int> if
|
||||||
|
// int is not in Ts...
|
||||||
|
else if (disjunction<std::is_same<int, Ts>...>::value && visitor.IsInt())
|
||||||
|
ReflectTag<int>(visitor, value);
|
||||||
|
else if (visitor.IsInt64())
|
||||||
|
ReflectTag<int64_t>(visitor, value);
|
||||||
|
else if (visitor.IsString())
|
||||||
|
ReflectTag<std::string>(visitor, value);
|
||||||
|
else
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
void operator()(Writer& visitor, std::variant<Ts...>& value) {
|
void operator()(Writer& visitor, std::variant<Ts...>& value) {
|
||||||
if (value.index() == N - 1)
|
if (value.index() == N - 1)
|
||||||
Reflect(visitor, std::get<N - 1>(value));
|
Reflect(visitor, std::get<N - 1>(value));
|
||||||
@ -198,15 +236,13 @@ struct ReflectVariant {
|
|||||||
};
|
};
|
||||||
|
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
struct ReflectVariant<1, Ts...> {
|
struct ReflectVariant<0, Ts...> {
|
||||||
void operator()(Writer& visitor, std::variant<Ts...>& value) {
|
void operator()(Writer& visitor, std::variant<Ts...>& value) {}
|
||||||
Reflect(visitor, std::get<0>(value));
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// std::variant (Writer only)
|
// std::variant
|
||||||
template <typename... Ts>
|
template <typename TVisitor, typename... Ts>
|
||||||
void Reflect(Writer& visitor, std::variant<Ts...>& value) {
|
void Reflect(TVisitor& visitor, std::variant<Ts...>& value) {
|
||||||
ReflectVariant<sizeof...(Ts), Ts...>()(visitor, value);
|
ReflectVariant<sizeof...(Ts), Ts...>()(visitor, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ class JsonReader : public Reader {
|
|||||||
bool IsNull() override { return m_->IsNull(); }
|
bool IsNull() override { return m_->IsNull(); }
|
||||||
bool IsArray() override { return m_->IsArray(); }
|
bool IsArray() override { return m_->IsArray(); }
|
||||||
bool IsInt() override { return m_->IsInt(); }
|
bool IsInt() override { return m_->IsInt(); }
|
||||||
// bool IsInt64() override { return m_->IsInt64(); }
|
bool IsInt64() override { return m_->IsInt64(); }
|
||||||
// bool IsUint64() override { return m_->IsUint64(); }
|
// bool IsUint64() override { return m_->IsUint64(); }
|
||||||
bool IsString() override { return m_->IsString(); }
|
bool IsString() override { return m_->IsString(); }
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@ class MessagePackReader : public Reader {
|
|||||||
return oh_.get().type == msgpack::type::POSITIVE_INTEGER ||
|
return oh_.get().type == msgpack::type::POSITIVE_INTEGER ||
|
||||||
oh_.get().type == msgpack::type::NEGATIVE_INTEGER;
|
oh_.get().type == msgpack::type::NEGATIVE_INTEGER;
|
||||||
}
|
}
|
||||||
|
bool IsInt64() override { return IsInt(); }
|
||||||
bool IsString() override { return oh_.get().type == msgpack::type::STR; }
|
bool IsString() override { return oh_.get().type == msgpack::type::STR; }
|
||||||
|
|
||||||
void GetNull() override { pk_->next(oh_); }
|
void GetNull() override { pk_->next(oh_); }
|
||||||
|
Loading…
Reference in New Issue
Block a user