Property.h 3.15 KiB
/* Copyright (C) 2023 FIAS Frankfurt Institute for Advanced Studies, Frankfurt / Main
SPDX-License-Identifier: GPL-3.0-only
Authors: Felix Weiglhofer [committer] */
#ifndef CBM_YAML_PROPERTY_H
#define CBM_YAML_PROPERTY_H
#pragma once
#include "Definitions.h"
#include <optional>
#include <string_view>
#include <tuple>
#include <yaml-cpp/emittermanip.h>
namespace cbm::algo::yaml
{
template<typename Class, typename T>
class Property {
private:
T Class::*fMember;
std::string_view fKey;
std::string_view fDescription;
std::optional<YAML::EMITTER_MANIP> fFormat;
std::optional<YAML::EMITTER_MANIP> fFormatEntries;
public:
using ClassType = Class;
using ValueType = T;
Property() = delete;
constexpr Property(T Class::*member, std::string_view key, std::string_view description = "",
std::optional<YAML::EMITTER_MANIP> fmt = {}, std::optional<YAML::EMITTER_MANIP> fmtEntries = {})
: fMember(member)
, fKey(key)
, fDescription(description)
, fFormat(fmt)
, fFormatEntries(fmtEntries)
{
}
Property(const Property&) = delete;
Property& operator=(const Property&) = delete;
Property(Property&&) = default;
Property& operator=(Property&&) = default;
std::string_view Key() const { return fKey; }
std::string_view Description() const { return fDescription; }
std::optional<YAML::EMITTER_MANIP> Format() const { return fFormat; }
std::optional<YAML::EMITTER_MANIP> FormatEntries() const { return fFormatEntries; }
T& Get(Class& object) const { return object.*fMember; }
const T& Get(const Class& object) const { return object.*fMember; }
void Set(Class& object, const T& value) const { object.*fMember = value; }
};
template<typename Class, typename T>
Property(T Class::*member, std::string_view key, std::string_view description) -> Property<Class, T>;
} // namespace cbm::algo::yaml
#define CBM_YAML_PROPERTIES(...) \
public: \
static constexpr auto Properties = std::make_tuple(__VA_ARGS__)
/**
* @brief Optional tag to specify a formatting of the class (YAML::Flow vs YAML::Block)
*/
#define CBM_YAML_FORMAT(tag) \
public: \
static constexpr std::optional<YAML::EMITTER_MANIP> FormatAs = tag
/**
* @brief Optional flag to indicate that the class should be treated like a type
* of it's property. Only has an effect on classes with a single property.
*
* @note This is useful to make some config files more compact.
*/
#define CBM_YAML_MERGE_PROPERTY() \
public: \
static constexpr bool MergeProperty = true
#endif // CBM_YAML_PROPERTY_H