A bug was discovered in glaze which prevented valid toml output. We have switched to toml++ and reflect-cpp. The interface has remained the same so this should not break any code
222 lines
7.6 KiB
C++
222 lines
7.6 KiB
C++
#ifndef RFL_PARSING_PARENT_HPP_
|
|
#define RFL_PARSING_PARENT_HPP_
|
|
|
|
#include <string_view>
|
|
#include <type_traits>
|
|
|
|
#include "../always_false.hpp"
|
|
#include "schemaful/IsSchemafulWriter.hpp"
|
|
#include "supports_attributes.hpp"
|
|
|
|
namespace rfl::parsing {
|
|
|
|
template <class W>
|
|
struct Parent {
|
|
using OutputArrayType = typename W::OutputArrayType;
|
|
using OutputObjectType = typename W::OutputObjectType;
|
|
using OutputVarType = typename W::OutputVarType;
|
|
|
|
struct Array {
|
|
OutputArrayType* arr_;
|
|
};
|
|
|
|
// For schemaful formats only.
|
|
template <class T>
|
|
struct Map {
|
|
std::string_view name_;
|
|
T* map_;
|
|
};
|
|
|
|
struct Object {
|
|
std::string_view name_;
|
|
OutputObjectType* obj_;
|
|
bool is_attribute_ = false;
|
|
Object as_attribute() const { return Object{name_, obj_, true}; }
|
|
};
|
|
|
|
// For schemaful formats only.
|
|
template <class T>
|
|
struct Union {
|
|
size_t index_;
|
|
T* union_;
|
|
};
|
|
|
|
struct Root {};
|
|
|
|
template <class ParentType>
|
|
static OutputArrayType add_array(const W& _w, const size_t _size,
|
|
const ParentType& _parent) {
|
|
using Type = std::remove_cvref_t<ParentType>;
|
|
if constexpr (std::is_same<Type, Array>()) {
|
|
return _w.add_array_to_array(_size, _parent.arr_);
|
|
|
|
} else if constexpr (std::is_same<Type, Object>()) {
|
|
return _w.add_array_to_object(_parent.name_, _size, _parent.obj_);
|
|
|
|
} else if constexpr (std::is_same<Type, Root>()) {
|
|
return _w.array_as_root(_size);
|
|
|
|
} else if constexpr (schemaful::IsSchemafulWriter<W>) {
|
|
if constexpr (std::is_same<Type, Map<typename W::OutputMapType>>()) {
|
|
return _w.add_array_to_map(_parent.name_, _size, _parent.map_);
|
|
} else if constexpr (std::is_same<Type,
|
|
Union<typename W::OutputUnionType>>()) {
|
|
return _w.add_array_to_union(_parent.index_, _size, _parent.union_);
|
|
} else {
|
|
static_assert(always_false_v<Type>, "Unsupported option.");
|
|
}
|
|
|
|
} else {
|
|
static_assert(always_false_v<Type>, "Unsupported option.");
|
|
}
|
|
}
|
|
|
|
// For schemaful formats only.
|
|
template <class ParentType>
|
|
static auto add_map(const W& _w, const size_t _size,
|
|
const ParentType& _parent) {
|
|
using Type = std::remove_cvref_t<ParentType>;
|
|
if constexpr (std::is_same<Type, Array>()) {
|
|
return _w.add_map_to_array(_size, _parent.arr_);
|
|
|
|
} else if constexpr (std::is_same<Type, Map<typename W::OutputMapType>>()) {
|
|
return _w.add_map_to_map(_parent.name_, _size, _parent.map_);
|
|
|
|
} else if constexpr (std::is_same<Type, Object>()) {
|
|
return _w.add_map_to_object(_parent.name_, _size, _parent.obj_);
|
|
|
|
} else if constexpr (std::is_same<Type,
|
|
Union<typename W::OutputUnionType>>()) {
|
|
return _w.add_map_to_union(_parent.index_, _size, _parent.union_);
|
|
|
|
} else if constexpr (std::is_same<Type, Root>()) {
|
|
return _w.map_as_root(_size);
|
|
|
|
} else {
|
|
static_assert(always_false_v<Type>, "Unsupported option.");
|
|
}
|
|
}
|
|
|
|
template <class ParentType>
|
|
static OutputObjectType add_object(const W& _w, const size_t _size,
|
|
const ParentType& _parent) {
|
|
using Type = std::remove_cvref_t<ParentType>;
|
|
if constexpr (std::is_same<Type, Array>()) {
|
|
return _w.add_object_to_array(_size, _parent.arr_);
|
|
|
|
} else if constexpr (std::is_same<Type, Object>()) {
|
|
return _w.add_object_to_object(_parent.name_, _size, _parent.obj_);
|
|
|
|
} else if constexpr (std::is_same<Type, Root>()) {
|
|
return _w.object_as_root(_size);
|
|
|
|
} else if constexpr (schemaful::IsSchemafulWriter<W>) {
|
|
if constexpr (std::is_same<Type, Map<typename W::OutputMapType>>()) {
|
|
return _w.add_object_to_map(_parent.name_, _size, _parent.map_);
|
|
} else if constexpr (std::is_same<Type,
|
|
Union<typename W::OutputUnionType>>()) {
|
|
return _w.add_object_to_union(_parent.index_, _size, _parent.union_);
|
|
} else {
|
|
static_assert(always_false_v<Type>, "Unsupported option.");
|
|
}
|
|
|
|
} else {
|
|
static_assert(always_false_v<Type>, "Unsupported option.");
|
|
}
|
|
}
|
|
|
|
template <class ParentType>
|
|
static OutputVarType add_null(const W& _w, const ParentType& _parent) {
|
|
using Type = std::remove_cvref_t<ParentType>;
|
|
if constexpr (std::is_same<Type, Array>()) {
|
|
return _w.add_null_to_array(_parent.arr_);
|
|
|
|
} else if constexpr (std::is_same<Type, Object>()) {
|
|
if constexpr (supports_attributes<std::remove_cvref_t<W>>) {
|
|
return _w.add_null_to_object(_parent.name_, _parent.obj_,
|
|
_parent.is_attribute_);
|
|
} else {
|
|
return _w.add_null_to_object(_parent.name_, _parent.obj_);
|
|
}
|
|
|
|
} else if constexpr (std::is_same<Type, Root>()) {
|
|
return _w.null_as_root();
|
|
|
|
} else if constexpr (schemaful::IsSchemafulWriter<W>) {
|
|
if constexpr (std::is_same<Type, Map<typename W::OutputMapType>>()) {
|
|
return _w.add_null_to_map(_parent.name_, _parent.map_);
|
|
} else if constexpr (std::is_same<Type,
|
|
Union<typename W::OutputUnionType>>()) {
|
|
return _w.add_null_to_union(_parent.index_, _parent.union_);
|
|
} else {
|
|
static_assert(always_false_v<Type>, "Unsupported option.");
|
|
}
|
|
|
|
} else {
|
|
static_assert(always_false_v<Type>, "Unsupported option.");
|
|
}
|
|
}
|
|
|
|
// For schemaful formats only.
|
|
template <class ParentType>
|
|
static auto add_union(const W& _w, const ParentType& _parent) {
|
|
using Type = std::remove_cvref_t<ParentType>;
|
|
if constexpr (std::is_same<Type, Array>()) {
|
|
return _w.add_union_to_array(_parent.arr_);
|
|
|
|
} else if constexpr (std::is_same<Type, Map<typename W::OutputMapType>>()) {
|
|
return _w.add_union_to_map(_parent.name_, _parent.map_);
|
|
|
|
} else if constexpr (std::is_same<Type, Object>()) {
|
|
return _w.add_union_to_object(_parent.name_, _parent.obj_);
|
|
|
|
} else if constexpr (std::is_same<Type,
|
|
Union<typename W::OutputUnionType>>()) {
|
|
return _w.add_union_to_union(_parent.index_, _parent.union_);
|
|
|
|
} else if constexpr (std::is_same<Type, Root>()) {
|
|
return _w.union_as_root();
|
|
|
|
} else {
|
|
static_assert(always_false_v<Type>, "Unsupported option.");
|
|
}
|
|
}
|
|
|
|
template <class ParentType, class T>
|
|
static OutputVarType add_value(const W& _w, const T& _var,
|
|
const ParentType& _parent) {
|
|
using Type = std::remove_cvref_t<ParentType>;
|
|
if constexpr (std::is_same<Type, Array>()) {
|
|
return _w.add_value_to_array(_var, _parent.arr_);
|
|
|
|
} else if constexpr (std::is_same<Type, Object>()) {
|
|
if constexpr (supports_attributes<std::remove_cvref_t<W>>) {
|
|
return _w.add_value_to_object(_parent.name_, _var, _parent.obj_,
|
|
_parent.is_attribute_);
|
|
} else {
|
|
return _w.add_value_to_object(_parent.name_, _var, _parent.obj_);
|
|
}
|
|
|
|
} else if constexpr (std::is_same<Type, Root>()) {
|
|
return _w.value_as_root(_var);
|
|
|
|
} else if constexpr (schemaful::IsSchemafulWriter<W>) {
|
|
if constexpr (std::is_same<Type, Map<typename W::OutputMapType>>()) {
|
|
return _w.add_value_to_map(_parent.name_, _var, _parent.map_);
|
|
} else if constexpr (std::is_same<Type,
|
|
Union<typename W::OutputUnionType>>()) {
|
|
return _w.add_value_to_union(_parent.index_, _var, _parent.union_);
|
|
} else {
|
|
static_assert(always_false_v<Type>, "Unsupported option.");
|
|
}
|
|
|
|
} else {
|
|
static_assert(always_false_v<Type>, "Unsupported option.");
|
|
}
|
|
}
|
|
};
|
|
|
|
} // namespace rfl::parsing
|
|
|
|
#endif
|