Branch data Line data Source code
1 : : // *****************************************************************************
2 : : /*!
3 : : \file src/Control/Keyword.hpp
4 : : \copyright 2012-2015 J. Bakosi,
5 : : 2016-2018 Los Alamos National Security, LLC.,
6 : : 2019-2021 Triad National Security, LLC.
7 : : All rights reserved. See the LICENSE file for details.
8 : : \brief Generic definition of a keyword
9 : : \details Generic definition of all keywords - both command-line arguments
10 : : and control file keywords.
11 : : */
12 : : // *****************************************************************************
13 : : #ifndef Keyword_h
14 : : #define Keyword_h
15 : :
16 : : #include <optional>
17 : :
18 : : #include "NoWarning/set.hpp"
19 : : #include "NoWarning/pegtl.hpp"
20 : :
21 : : #include "Has.hpp"
22 : : #include "Escaper.hpp"
23 : :
24 : : namespace tk {
25 : :
26 : : //! Helper to declare a set of command line keywords
27 : : //! \details This ensures that a compile-error is generated if there is no alias
28 : : //! defined for the keyword, and also if the aliases are non-unique.
29 : : template< typename... T >
30 : : class cmd_keywords {
31 : : public:
32 : : using set = brigand::set< T... >;
33 : : private:
34 : : template< typename K > using alias = typename K::info::alias::type;
35 : : using aliases = brigand::set< alias<T>... >;
36 : : };
37 : :
38 : : } // tk::
39 : :
40 : : namespace kw {
41 : :
42 : : using namespace tao;
43 : :
44 : : //! \brief Keyword alias helper
45 : : //! \details This struct is used to define both a type and a value for a keyword
46 : : //! alias, which is a single character. Used for command-line arguments, e.g.,
47 : : //! --help, -h, where 'h' is the alias for keyword 'help'.
48 : : //! \see Control/Keywords.h
49 : : template< int Char >
50 : : struct Alias {
51 : : using type = pegtl::one< Char >;
52 : : static const int value = Char;
53 : : };
54 : :
55 : : //! \brief Generic definition of a keyword
56 : : //! \details A keyword is a struct that collects the information that makes up a
57 : : //! keyword. The requirement on the first template argument, Info, is that it
58 : : //! must define the name(), shortDescription(,) and longDescription() member
59 : : //! functions returning compile-time (static) std::strings. The
60 : : //! shortDescription() member function is used to return a short description
61 : : //! of what the keyword is used for, while the longDescription() member
62 : : //! function is used for a longer, e.g., a paragraph-long, description on
63 : : //! what the keyword can be used for and how it can and should be used. The
64 : : //! last template parameter is a pegtl string, a list of character constants,
65 : : //! specifying the case-sensitive characters that make up the keyword, which
66 : : //! is then matched by the parser. The keyword must be at least one character
67 : : //! long, but otherwise its length is only limited by the compiler's
68 : : //! recursion handling capability of variadic templates. While the name(),
69 : : //! shortDescription() and longDescription() member functions of Info are
70 : : //! required, there are also optional ones, such as
71 : : //! Info::exptect::description(), which, if defined, must also be static and
72 : : //! must return a std::string, describing the type the particular keyword
73 : : //! expects during parsing. This is optional since not every keyword expects
74 : : //! a value (or values) of a particular type. For example, the keyword 'end'
75 : : //! is simply used to close a block in the input file, and what follows does
76 : : //! not have a relationship to the keyword. A counterexample is is 'title',
77 : : //! which expects a double-quoted string immediately after the keyword
78 : : //! title'.
79 : : //! \see For example client-code and more detailed documentation on the possible
80 : : //! fields, see Control/Keywords.h.
81 : : template< typename Info, typename > struct keyword;
82 : : template< typename Info, char... Chars >
83 : : struct keyword< Info, pegtl::string< Chars... > > {
84 : :
85 : : //! Accessor to keyword as pegtl::string
86 : : using pegtl_string = pegtl::string< Chars... >;
87 : :
88 : : //! Accessor to keyword as std::string
89 : : //! \return Keyword as std::string
90 [ + - ][ + - ]: 60437 : static std::string string() { return kw::escaper< Chars... >::result(); }
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ - - ]
[ - - ][ - - ]
91 : :
92 : : //! Accessor to required short name of a keyword
93 : : //! \return Name of keyword as std::string
94 : : static std::string name() { return Info::name(); }
95 : :
96 : : //! Accessor to required short description of a keyword
97 : : //! \return Short help as std::string
98 : : static std::string shortDescription() { return Info::shortDescription(); }
99 : :
100 : : //! Accessor to required long description of a keyword
101 : : //! \return Long help as std::string
102 : : static std::string longDescription() { return Info::longDescription(); }
103 : :
104 : : //! Bring template argument 'Info' to scope as 'info'
105 : : //! \details This is used to access, e.g., Info::alias, etc., if exist.
106 : : //! \see tk::grm::alias
107 : : //! \see tk::grm::readcmd
108 : : using info = Info;
109 : :
110 : : //! Alias accessor for keyword
111 : : //! \return An initialized (or uninitialized) std::optional< std::string >
112 : : //! \details Though an alias is only a single character, it returns it as
113 : : //! std::string since pegtl::string returns std::string.
114 : : template< typename T = Info >
115 : 62458 : static std::optional< std::string > alias() {
116 : : if constexpr( tk::HasTypedef_alias_v< T > )
117 : 62458 : return std::string( 1, static_cast<char>( Info::alias::value ) );
118 : : else
119 : : return std::nullopt;
120 : : }
121 : :
122 : : //! Expected type description accessor for keyword
123 : : //! \return An initialized (or uninitialized) std::optional< std::string >
124 : : template< typename T = Info >
125 : 28745 : static std::optional< std::string > expt() {
126 : : if constexpr( tk::HasFunction_expect_description_v< T > )
127 : 28745 : return Info::expect::description();
128 : : else
129 : : return std::nullopt;
130 : : }
131 : :
132 : : //! Expected choices description accessor for a keyword
133 : : //! \return An initialized (or uninitialized) std::optional< std::string >
134 : : template< typename T = Info >
135 : 8565 : static std::optional< std::string > choices() {
136 : : if constexpr( tk::HasFunction_expect_choices_v< T > )
137 : 8565 : return Info::expect::choices();
138 : : else
139 : : return std::nullopt;
140 : : }
141 : :
142 : : //! Expected lower bound accessor for a keyword
143 : : //! \return An initialized (or uninitialized) std::optional< std::string >
144 : : template< typename T = Info >
145 : 8565 : static std::optional< std::string > lower() {
146 : : if constexpr( tk::HasVar_expect_lower_v< T > )
147 : 8565 : return std::to_string( Info::expect::lower );
148 : : else
149 : : return std::nullopt;
150 : : }
151 : :
152 : : //! Expected upper bound accessor for a keyword
153 : : //! \return An initialized (or uninitialized) std::optional< std::string >
154 : : template< typename T = Info >
155 : 8565 : static std::optional< std::string > upper() {
156 : : if constexpr( tk::HasVar_expect_upper_v< T > )
157 : 8565 : return std::to_string( Info::expect::upper );
158 : : else
159 : : return std::nullopt;
160 : : }
161 : : };
162 : :
163 : : } // kw::
164 : :
165 : : #endif // Keyword_h
|