.. _program_listing_file_src_common_options.h: Program Listing for File options.h ================================== |exhale_lsh| :ref:`Return to documentation for file ` (``src/common/options.h``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #pragma once // @TODO: to be removed when sure it works #define FASTOPT 1 // for diagnostics, 0 reverts to old behavior #include #include #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 { \ static Node encode(const registered& rhs) { \ type value = static_cast(rhs); \ return Node(value); \ } \ static bool decode(const Node& node, registered& rhs) { \ type value = node.as(); \ rhs = static_cast(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("var1", val1, "var2", val2, ...) template Options(const std::string& key, T value, Args&&... moreArgs) : Options() { set(key, value, std::forward(moreArgs)...); } Options(const YAML::Node& node) : Options() { merge(node); } // constructor that clones and zero or more updates // options->with("var1", val1, "var2", val2, ...) template Ptr with(Args&&... args) const { auto options = New(*this); options->set(std::forward(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); std::string asYamlString(); template void set(const std::string& key, T value) { options_[key] = value; #if FASTOPT setLazyRebuild(); #endif } // set multiple // options->set("var1", val1, "var2", val2, ...) template void set(const std::string& key, T value, Args&&... moreArgs) { set(key, value); set(std::forward(moreArgs)...); #if FASTOPT setLazyRebuild(); #endif } template 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(); #else ABORT_IF(!has(key), "Required option '{}' has not been set", key); return options_[key].as(); #endif } template T get(const std::string& key) const { return get(key.c_str()); } template T get(const char* const key, T defaultValue) const { #if FASTOPT lazyRebuild(); if(has(key)) return fastOptions_[key].as(); #else if(has(key)) return options_[key].as(); #endif else return defaultValue; } template T get(const std::string& key, T defaultValue) const { return get(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