.. _program_listing_file_src_common_fastopt.cpp: Program Listing for File fastopt.cpp ==================================== |exhale_lsh| :ref:`Return to documentation for file ` (``src/common/fastopt.cpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #include "common/fastopt.h" #include namespace marian { const std::unique_ptr FastOpt::uniqueNullPtr{nullptr}; // see fastopt.h for comments namespace fastopt_helpers { // helper structs for dynamic type conversion and specializations // for different conversion scenarios. // general template, mostly for numerical and logical types template struct Convert { static inline To apply(const From& from) { return (To)from; } }; // specialization for translating from string, @TODO check if this is required at all, mostly for compilation now. template struct Convert { static inline To apply(const std::string& /* from */) { ABORT("Not implemented"); } }; // convert anything to string, checked at compile-time template struct Convert { static inline std::string apply(const From& from) { return std::to_string(from); } }; // do nothing conversion for std::string template <> struct Convert { static inline std::string apply(const std::string& from) { return from; } }; // helper class for FastOpt::as() used for specializations template T As::apply(const FastOpt& node) { ABORT_IF(!node.isScalar(), "Node is not a scalar node"); if(node.isBool()) return Convert::apply(node.value_.as()); else if(node.isInt()) return Convert::apply(node.value_.as()); else if(node.isFloat()) return Convert::apply(node.value_.as()); else if(node.isString()) return Convert::apply(node.value_.as()); else { ABORT("Casting of value failed"); } } // specializations for simple types template struct As; template struct As; template struct As; template struct As; template struct As; template struct As; // specialization of above class for std::vector template std::vector As>::apply(const FastOpt& node) { ABORT_IF(!node.isSequence(), "Node is not a sequence node"); std::vector seq; for(const auto& elem : node.array_) seq.push_back(elem->as()); return seq; } // specializations for simple vector types template struct As>; template struct As>; // Windows, Linux based OS and Mac have different type definitions for 'unsigned long'. // So, we need an explicit definitions for uint64_t, that cover different platforms. // Otherwise, there's a linking error on windows or Linux or Mac. // https://software.intel.com/en-us/articles/size-of-long-integer-type-on-different-architecture-and-os/ // https://stackoverflow.com/questions/32021860/c-should-you-size-t-with-a-regular-array // MacOS: size_t = unsigned long (8 bytes), uint64_t = unsigned long long (8 bytes) // Linux: size_t = unsigned long (8 bytes), uint64_t = unsigned long (8 bytes) // Windows: size_t = unsigned long long (8 bytes), uint64_t = unsigned long long (8 bytes) template struct As>; template struct As>; template struct As>; template struct As>; template struct As>; // specialization of above class for std::pair template std::pair As>::apply(const FastOpt& node) { ABORT_IF(!node.isSequence(), "Node is not a sequence node"); ABORT_IF(node.size() != 2, "Sequence must contain two elements in order to convert to pair"); return std::make_pair(node[0].as(), node[1].as()); } template struct As>; } }