Skip to content

Better support for "default" #973

Description

@kunaltyagi

YAML is often used for configuration input, and it's a bit difficult to manage defaults:

Current:

inline bool validField(const YAML::Node& node, const std::string& field) noexcept {
    if (node.IsDefined() && node[field].IsDefined() && !node[field].IsNull()) {
        return true;
    }
    return false;
}

// The convert struct is helpful only once: for reading the defaults
// default = node.as<Cfg>();

Cfg readConfig(const YAML::Node& node, const Cfg& default) {
    Cfg config = default;
    if (validField(node, "first")) {  config.first = node["first"].as<decltype(config.first)>();
	// ...
	// repeat for N number of fields
	return config;
}

Proposed:

Cfg readConfig(const YAML::Node& node, Cfg default) {
	// Note the change from const reference to value for default
	node.into<Cfg>(default);  // 100% usage of convert struct
	return default;
}

Roadmap:

  • Add templated update function to Node. Bikeshedding on name is on the table. into just reads nice
  • Update the as_if struct with a function, say update, in node/impl.h to not create the default variable
  • The into (newly added templated function) calls the update function.

Proposed change in as_if:

template <typename T, typename S>
struct as_if {
  explicit as_if(const Node& node_) : node(node_) {}
  const Node& node;

  // current, can be replaced with the newer function
  T operator()(const S& fallback) const {
    if (!node.m_pNode)
      return fallback;

    T t;
    if (convert<T>::decode(node, t))
      return t;
    return fallback;
  }

  // new
  bool update(S& incoming) {
	if (!node.m_pNode)
	  return false;
	if (convert<T>::decode(node, incoming))
	  return true;
	return false;
  }

  // compilers are smart enough to reorder `T t` after the inlining of `node.m_pNode` check
  T operator()(const S& fallback) const {
	T t;
	if (update(t))
	  return t;
	return fallback;
  }	
};

I can create a PR if needed, but I'm confused about the overloads for S = void case

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions