yaml-cpp
yaml-cpp copied to clipboard
Implement a customization point for types not default constructible
trafficstars
This patch adds a customization point YAML::decode_dispatcher<T>::dispatch which:
- allows decoding types that aren't default constructible,
- delegates to
YAML::convert<T>::decodeby default for backward compatibility, - is enabled only when compiled with C++17 or newer since it depends on
std::optional.
Notes:
- Compiling with C++17 automatically enables this feature.
- Relevant tests are added. Tested it locally (gcc 10.2 on debian buster) to confirm all tests passes with both C++11 & C++17.
YAML_CPP_HAS_DECODE_DISPATCHERmacro is exposed allowing checking this feature.- Its signature has an
Enabletemplate parameter giving more flexibility, e.g. to allow SFINAE downstream:
namespace YAML {
template <typename T, typename Enable = void>
struct decode_dispatcher {
static std::optional<T> dispatch(const Node& node) {
// ...
}
};
}
Example:
#include <yaml-cpp/node/impl.h>
struct Vec3 {
double x, y, z;
Vec3(double x, double y, double z) : x(x), y(y), z(z) {}
// ...
};
namespace YAML {
template<>
struct decode_dispatcher<Vec3> {
static std::optional<Vec3> dispatch(const Node& node) {
if(!node.IsSequence() || node.size() != 3)
return std::nullopt;
return Vec3(
node[0].as<double>(),
node[1].as<double>(),
node[2].as<double>()
);
}
};
}
Possibly closes: #993.