ezconfig
Create C++ Objects from Yaml and Json
Loading...
Searching...
No Matches
yaml.hpp
Go to the documentation of this file.
1// Copyright (c) 2023 Petter Nilsson. MIT License. https://github.com/pettni/ezconfig
2
10#pragma once
11
12#include <yaml-cpp/yaml.h>
13
14#include "factory.hpp"
15#include "yaml_fwd.hpp"
16
29#define EZ_YAML_DEFINE(Base) \
30 EZ_FACTORY_DEFINE(Base, const YAML::Node &); \
31 template std::unique_ptr<Base> ezconfig::yaml::Create(const YAML::Node &); \
32 template struct YAML::convert<std::shared_ptr<Base>>; \
33 template struct YAML::convert<std::unique_ptr<Base>>
34
53#define EZ_YAML_REGISTER(Base, tag, Derived, ...) \
54 EZ_STATIC_INVOKE(&ezconfig::yaml::Add<Base, Derived __VA_OPT__(, ) __VA_ARGS__>, tag)
55
56namespace ezconfig::yaml {
57
58// clang-format off
59template<typename T>
60concept YamlParseable = requires(const YAML::Node & y) {
61 {y.as<T>()} -> std::convertible_to<T>;
62};
63// clang-format on
64
78template<typename Base, typename Derived, typename Intermediate = Derived>
79 requires(
80 std::is_base_of_v<Base, Derived> && YamlParseable<Intermediate>
81 && std::is_constructible_v<Derived, Intermediate &&>)
82void Add(const std::string & tag)
83{
84 if (tag.size() < 2 || tag[0] != '!') { throw std::logic_error("yaml tag must start with !"); }
85 auto creator = [](const YAML::Node & y) { return std::make_unique<Derived>(y.as<Intermediate>()); };
86 EZ_FACTORY_INSTANCE(Base, const YAML::Node &).add(tag, std::move(creator));
87}
88
89template<typename Base>
90std::unique_ptr<Base> Create(const YAML::Node & y)
91{
92 return EZ_FACTORY_INSTANCE(Base, const YAML::Node &).create(y.Tag(), y);
93}
94
95} // namespace ezconfig::yaml
96
97template<ezconfig::yaml::Constructible Base>
98bool YAML::convert<std::shared_ptr<Base>>::decode(const YAML::Node & y, std::shared_ptr<Base> & ptr)
99{
100 ptr = ::ezconfig::yaml::Create<Base>(y);
101 return true;
102}
103
104template<ezconfig::yaml::Constructible Base>
105bool YAML::convert<std::unique_ptr<Base>>::decode(const YAML::Node & y, std::unique_ptr<Base> & ptr)
106{
107 ptr = ::ezconfig::yaml::Create<Base>(y);
108 return true;
109}
Factory base class.
Yaml factory forward declarations.