Program Listing for File options.h¶
↰ Return to documentation for file (src/common/options.h
)
#pragma once
// @TODO: to be removed when sure it works
#define FASTOPT 1 // for diagnostics, 0 reverts to old behavior
#include <sstream>
#include <string>
#include "common/definitions.h"
#include "3rd_party/yaml-cpp/yaml.h"
#ifdef FASTOPT
#include "common/fastopt.h"
#endif
#define YAML_REGISTER_TYPE(registered, type) \
namespace YAML { \
template <> \
struct convert<registered> { \
static Node encode(const registered& rhs) { \
type value = static_cast<type>(rhs); \
return Node(value); \
} \
static bool decode(const Node& node, registered& rhs) { \
type value = node.as<type>(); \
rhs = static_cast<registered>(value); \
return true; \
} \
}; \
}
namespace marian {
class Options {
protected:
YAML::Node options_; // YAML options use for parsing, modification and printing
#if FASTOPT
// Only to be modified in lazyRebuild and setLazyRebuild
mutable FastOpt fastOptions_; // FastOpt used for fast lookup, lazily rebuilt from YYAML whenever required
mutable bool lazyRebuildPending_{false}; // flag if need to lazily rebuild
// set flag that a rebuild is required
void setLazyRebuild() const {
lazyRebuildPending_ = true;
}
// check if rebuild is required, rebuild, unset flag.
void lazyRebuild() const {
if(lazyRebuildPending_) {
FastOpt temp(options_);
fastOptions_.swap(temp);
lazyRebuildPending_ = false;
}
}
#endif
public:
Options();
Options(const Options& other);
// constructor with one or more key-value pairs
// New<Options>("var1", val1, "var2", val2, ...)
template <typename T, typename... Args>
Options(const std::string& key, T value, Args&&... moreArgs) : Options() {
set(key, value, std::forward<Args>(moreArgs)...);
}
Options(const YAML::Node& node) : Options() {
merge(node);
}
// constructor that clones and zero or more updates
// options->with("var1", val1, "var2", val2, ...)
template <typename... Args>
Ptr<Options> with(Args&&... args) const {
auto options = New<Options>(*this);
options->set(std::forward<Args>(args)...);
return options;
}
Options clone() const;
// Do not allow access to internal YAML object as changes on the outside are difficult to track
// and mess with the rebuilding of the fast options lookup. Hence only return a clone which guarentees
// full encapsulation.
YAML::Node cloneToYamlNode() const;
void parse(const std::string& yaml);
void merge(const YAML::Node& node, bool overwrite = false);
void merge(Ptr<Options> options);
std::string asYamlString();
template <typename T>
void set(const std::string& key, T value) {
options_[key] = value;
#if FASTOPT
setLazyRebuild();
#endif
}
// set multiple
// options->set("var1", val1, "var2", val2, ...)
template <typename T, typename... Args>
void set(const std::string& key, T value, Args&&... moreArgs) {
set(key, value);
set(std::forward<Args>(moreArgs)...);
#if FASTOPT
setLazyRebuild();
#endif
}
template <typename T>
T get(const char* const key) const {
#if FASTOPT
lazyRebuild();
ABORT_IF(!has(key), "Required option '{}' has not been set", key);
return fastOptions_[key].as<T>();
#else
ABORT_IF(!has(key), "Required option '{}' has not been set", key);
return options_[key].as<T>();
#endif
}
template <typename T>
T get(const std::string& key) const {
return get<T>(key.c_str());
}
template <typename T>
T get(const char* const key, T defaultValue) const {
#if FASTOPT
lazyRebuild();
if(has(key))
return fastOptions_[key].as<T>();
#else
if(has(key))
return options_[key].as<T>();
#endif
else
return defaultValue;
}
template <typename T>
T get(const std::string& key, T defaultValue) const {
return get<T>(key.c_str(), defaultValue);
}
bool hasAndNotEmpty(const char* const key) const;
bool hasAndNotEmpty(const std::string& key) const;
bool has(const char* const key) const;
bool has(const std::string& key) const;
};
} // namespace marian