Line data Source code
1 1 : // Distributed under the MIT License. 2 : // See LICENSE.txt for details. 3 : 4 : /// \file 5 : /// Defines classes and functions for making classes creatable from 6 : /// input files. 7 : 8 : #pragma once 9 : 10 : #include <memory> 11 : #include <string> 12 : #include <type_traits> 13 : 14 : #include "Options/Context.hpp" 15 : #include "Utilities/NoSuchType.hpp" 16 : #include "Utilities/TMPL.hpp" 17 : #include "Utilities/TypeTraits/IsA.hpp" 18 : 19 : /// \cond 20 : namespace YAML { 21 : class Node; 22 : } // namespace YAML 23 : /// \endcond 24 : 25 : /// Utilities for parsing input files. 26 : namespace Options { 27 : /// \ingroup OptionParsingGroup 28 : /// The type that options are passed around as. Contains YAML node 29 : /// data and an Context. 30 : /// 31 : /// \note To use any methods on this class in a concrete function you 32 : /// must include ParseOptions.hpp, but you do *not* need to include 33 : /// that header to use this in an uninstantiated 34 : /// `create_from_yaml::create` function. 35 1 : class Option { 36 : public: 37 0 : const Context& context() const; 38 : 39 : /// Append a line to the contained context. 40 1 : void append_context(const std::string& context); 41 : 42 : /// Convert to an object of type `T`. 43 : template <typename T, typename Metavariables = NoSuchType> 44 1 : T parse_as() const; 45 : 46 : /// \note This constructor overwrites the mark data in the supplied 47 : /// context with the one from the node. 48 : /// 49 : /// \warning This method is for internal use of the option parser. 50 1 : explicit Option(YAML::Node node, Context context = {}); 51 : 52 : /// \warning This method is for internal use of the option parser. 53 1 : explicit Option(Context context); 54 : 55 : /// \warning This method is for internal use of the option parser. 56 1 : const YAML::Node& node() const; 57 : 58 : /// Sets the node and updates the context's mark to correspond to it. 59 : /// 60 : /// \warning This method is for internal use of the option parser. 61 1 : void set_node(YAML::Node node); 62 : 63 : private: 64 0 : std::unique_ptr<YAML::Node> node_; 65 0 : Context context_; 66 : }; 67 : 68 : /// \ingroup OptionParsingGroup 69 : /// Used by the parser to create an object. The default action is to 70 : /// parse options using `T::options`. This struct may be specialized 71 : /// to change that behavior for specific types. 72 : /// 73 : /// Do not call create directly. Use Option::parse_as instead. 74 : template <typename T> 75 1 : struct create_from_yaml { 76 : template <typename Metavariables> 77 0 : static T create(const Option& options); 78 : }; 79 : 80 : /// Provide multiple ways to construct a class. 81 : /// 82 : /// This type may be included in an option list along with option 83 : /// tags. When creating the class, the parser will choose one of the 84 : /// lists of options to use, depending on the user input. 85 : /// 86 : /// The class must be prepared to accept any of the possible 87 : /// alternatives as arguments to its constructor. To disambiguate 88 : /// multiple alternatives with the same types, a constructor may take 89 : /// the full list of option tags expected as its first argument. 90 : /// 91 : /// \snippet Test_Options.cpp alternatives 92 : template <typename... AlternativeLists> 93 1 : struct Alternatives { 94 : static_assert(sizeof...(AlternativeLists) >= 1, 95 : "Option alternatives must provide at least one alternative."); 96 : static_assert( 97 : tmpl::all<tmpl::list<tt::is_a<tmpl::list, AlternativeLists>...>>::value, 98 : "Option alternatives must be given as tmpl::lists."); 99 : static_assert( 100 : tmpl::none< 101 : tmpl::list<std::is_same<tmpl::list<>, AlternativeLists>...>>::value, 102 : "All option alternatives must have at least one option."); 103 : }; 104 : } // namespace Options