Project

General

Profile

Fhiclcpp types in detail » History » Version 50

Version 49 (Kyle Knoepfel, 12/16/2015 09:41 AM) → Version 50/56 (Kyle Knoepfel, 12/16/2015 10:23 AM)

h1. @fhiclcpp@ types in detail

{{toc}}

----

h1(#ctors). Parameter constructors



h2(#ctors_rules). %{color:blue}General comments% rules%

For each of the @fhiclcpp@ types, the following rules apply:
* The @Name@ argument is required for each of the @fhiclcpp@ types. required.
* Neither the @Table<T>@ parameter nor any of the @Optional*@ parameters support a default value.
* None of the examples below include a use of the conditional configuration facility (i.e. @std::function<bool()> maybeUse@). An explanation of how users can take advantage of the facility is given [[Conditional_configuration|here]].
* The @Name&&@ and @Comment&&@ references are explained [[System_details|here]]. The double-ampersand is a way of (almost unconditionally) requiring users to provide a temporary object by specifying (e.g.) @Name("some_name")@ for each parameter.
*


h3(#opt_comment). Note about optional parameters

In addition to @Optional*@ parameters not supporting default values, they also cannot be used as template arguments to *any* @fhiclcpp@ types:


<pre><code class="cpp">
Sequence< OptionalSequence<int> > e1 { ... }; // error
Sequence< OptionalSequence<int,2u> > e2 { ... }; // error
Sequence< OptionalTuple<int,double> > e3 { ... }; // error
OptionalSequence< Sequence<int> > ok { ... }; // ok
</code></pre>



h2(#atom). %{color:blue}@Atom<T>@%

h3. Allowed constructors

<pre><code class="cpp">
explicit Atom(Name&&);
explicit Atom(Name&&, Comment&&);
explicit Atom(Name&&, Comment&&, std::function<bool()> maybeUse);

// c'tors supporting default values
explicit Atom(Name&&, T const& t);
explicit Atom(Name&&, Comment&&, T const& t);
explicit Atom(Name&&, Comment&&, std::function<bool()> maybeUse, T const& t);
</code></pre>

h3. Examples

<pre><code class="cpp">
Atom<int> var { Name("var") };
Atom<int> var { Name("var"), 9 };
Atom<int> var { Name("var"), Comment("A parameter description") };
Atom<int> var { Name("var"), Comment("A parameter description"), 9 };
</code></pre>

h2(#opt_atom). %{color:blue}@OptionalAtom<T>@%

h3. Allowed constructors

<pre><code class="cpp">
explicit OptionalAtom(Name&&);
explicit OptionalAtom(Name&&, Comment&&);
explicit OptionalAtom(Name&&, Comment&&, std::function<bool()> maybeUse);
</code></pre>

h3. Examples

<pre><code class="cpp">
OptionalAtom<int> var { Name("var") };
OptionalAtom<int> var { Name("var"), Comment("A parameter description") };
</code></pre>

h2(#opt_vector). %{color:blue}@OptionalSequence<T>@%

This class template is used for unbounded sequences.

h3. Allowed constructors

<pre><code class="cpp">
explicit OptionalSequence(Name&&);
explicit OptionalSequence(Name&&, Comment&&);
explicit OptionalSequence(Name&&, Comment&&, std::function<bool()> maybeUse);
</code></pre>

h3. Examples

<pre><code class="cpp">
OptionalSequence<int> seq { Name("seq") };
OptionalSequence<int> seq { Name("seq"), Comment("A sequence") };
</code></pre>

h2(#opt_array). %{color:blue}@OptionalSequence<T,std::size_t>@%

This class template is used for sequences of a specific length, known at compile time.

h3. Allowed constructors

<pre><code class="cpp">
explicit OptionalSequence(Name&&);
explicit OptionalSequence(Name&&, Comment&&);
explicit OptionalSequence(Name&&, Comment&&, std::function<bool()> maybeUse);
</code></pre>

h3. Examples

<pre><code class="cpp">
OptionalSequence<int,3u> seq { Name("seq") };
OptionalSequence<int,3u> seq { Name("seq"), Comment("A sequence") };
</code></pre>

h2(#opt_table). %{color:blue}@OptionalTable<T>@%

h3. Allowed constructors

<pre><code class="cpp">
explicit OptionalTable(Name&&);
explicit OptionalTable(Name&&, Comment&&);
explicit OptionalTable(Name&&, Comment&&, std::function<bool()> maybeUse);
</code></pre>

h3. Examples

<pre><code class="cpp">
OptionalTable<T> config { Name("config") };
OptionalTable<T> config { Name("config"), Comment("This describes the table") };
</code></pre>

h2(#opt_tuple). %{color:blue}@OptionalTuple<T...>@%

h3. Allowed constructors

<pre><code class="cpp">
explicit OptionalTuple(Name&&);
explicit OptionalTuple(Name&&, Comment&&);
explicit OptionalTuple(Name&&, Comment&&, std::function<bool()> maybeUse);
</code></pre>

h3. Examples

<pre><code class="cpp">
OptionalTuple<string,bool> tuple { Name("tuple") };
OptionalTuple<string,bool> tuple { Name("tuple"), Comment("A tuple") };
</code></pre>

h2(#vector). %{color:blue}@Sequence<T>@%

This class template is used for unbounded sequences. See the caveat below regarding narrowing conversions.

h3. Allowed constructors

<pre><code class="cpp">
explicit Sequence(Name&&);
explicit Sequence(Name&&, Comment&&);
explicit Sequence(Name&&, Comment&&, std::function<bool()> maybeUse);

// c'tors supporting default values
explicit Sequence(Name&&, std::vector<T> const& t);
explicit Sequence(Name&&, Comment&&, std::vector<T> const& t);
explicit Sequence(Name&&, Comment&&, std::function<bool()> maybeUse, std::vector<T> const& t);
</code></pre>

h3. Examples

<pre><code class="cpp">
Sequence<int> seq { Name("seq") };
Sequence<int> seq { Name("seq"), Comment("A sequence") };
Sequence<int> seq { Name("seq"), std::vector<int>{ 4, 5, 6, 7 } };
Sequence<int> seq { Name("seq"), { 4, 5, 6, 7 } };
Sequence<int> seq { Name("seq"), Comment("A sequence"), std::vector<int>{ 4, 5, 6, 7 } };
Sequence<int> seq { Name("seq"), Comment("A sequence"), { 4, 5, 6, 7 } };
</code></pre>

h3(#narrowing). Precaution regarding narrowing conversions and @std::initializer_list@ objects

The following configuration will trigger a compilation warning:

<pre><code class="cpp">
Sequence<int> seq1 { Name("seq1"), std::vector<int>{ 1, 2.4e-4 } };
Sequence<int> seq2 { Name("seq2"), { 1, 2.4e-4 } };
</code></pre>

that looks similar to this:

<pre>
warning: narrowing conversion of ‘2.4000000000000001e-4’ from ‘double’ to ‘int’ inside { } [-Wnarrowing]
</pre>

For build systems that convert compile-time warnings to errors, this will result in a build failure. The warning results from the nature of an @std::initializer_list@ object (also referred to as a brace-enclosed initializer), signified by @'{1, 2.4e-4}'@, which is used to initialize the sequence objects. For @std::initializer_list@ objects, narrowing conversions are not allowed--that is, converting a @double@ to an @int@ is an example of narrowing that results in loss of information. This is the most likely example of where you may find a narrowing conversion.

h2(#array). %{color:blue}@Sequence<T,std::size_t>@%

This class template is used for sequences of a specific length, known at compile time.

h3. Allowed constructors

_The @dtype@ is a type alias that allows users to specify as a default argument either an @std::array<T,N>@ object or a brace-enclosed @std::initializer_list<T>@ object. It is preferred that users provide an @std::array@ object as a default value since the size of the supplied array is checked against the expected size at compile time._

<pre><code class="cpp">
explicit Sequence(Name&&);
explicit Sequence(Name&&, Comment&&);
explicit Sequence(Name&&, Comment&&, std::function<bool()> maybeUse);

// c'tors supporting default values
explicit Sequence(Name&&, dtype const& t);
explicit Sequence(Name&&, Comment&&, dtype const& t);
explicit Sequence(Name&&, Comment&&, std::function<bool()> maybeUse, dtype const& t);
</code></pre>

h3. Examples

<pre><code class="cpp">
Sequence<int,3u> seq { Name("seq") };
Sequence<int,3u> seq { Name("seq"), Comment("A sequence") };
Sequence<int,3u> seq { Name("seq"), std::array<int,3u>{ 4, 5, 6 } };
Sequence<int,3u> seq { Name("seq"), { 4, 5, 6 } };
Sequence<int,3u> seq { Name("seq"), Comment("A sequence"), std::array<int,3u>{ 4, 5, 6 } };
Sequence<int,3u> seq { Name("seq"), Comment("A sequence"), { 4, 5, 6 } };
</code></pre>

The warning regarding narrowing conversions [[Fhiclcpp_types_in_detail#narrowing|above]] applies for bounded sequences as well.

h2(#table). %{color:blue}@Table<T>@%

h3. Allowed constructors

<pre><code class="cpp">
explicit Table(Name&&);
explicit Table(Name&&, Comment&&);
explicit Table(Name&&, Comment&&, std::function<bool()> maybeUse);
</code></pre>

h3. Examples

<pre><code class="cpp">
Table<T> config { Name("config") };
Table<T> config { Name("config"), Comment("This describes the table") };
</code></pre>

h2(#tuple). %{color:blue}@Tuple<T...>@%

h3. Allowed constructors

_The @dtype@ is a type alias that allows users to specify as a default argument either an @std::tuple<T...>@ object or a brace-enclosed initializer, which, in this case, is *not* an @std::initializer_list@ object._

<pre><code class="cpp">
explicit Tuple(Name&&);
explicit Tuple(Name&&, Comment&&);
explicit Tuple(Name&&, Comment&&, std::function<bool()> maybeUse);

// c'tors supporting default values
explicit Tuple(Name&&, dtype const& t);
explicit Tuple(Name&&, Comment&&, dtype const& t);
explicit Tuple(Name&&, Comment&&, std::function<bool()> maybeUse, dtype const& t);
</code></pre>

h3. Examples

<pre><code class="cpp">
Tuple<string,bool> tuple { Name("tuple") };
Tuple<string,bool> tuple { Name("tuple"), Comment("A tuple") };
Tuple<string,bool> tuple { Name("tuple"), std::tuple<string,bool>{"explicit?", true} };
Tuple<string,bool> tuple { Name("tuple"), {"compact?", true } };
Tuple<string,bool> tuple { Name("tuple"), Comment("A tuple"), std::tuple<string,bool>{ "Particle physics is neat.", true } };
Tuple<string,bool> tuple { Name("tuple"), Comment("A tuple"), { "This is false", false } };
</code></pre>

----

h1(#return). Standard parameters - return types

_[ In what follows, @array@, @string@, @tuple@, and @vector@ should each be prefaced with the appropriate namespace resolution: '@std::@'. ]_

|{background:#fba}. *@fhiclcpp@ parameter*|{background:#fba}. *Function call*|{background:#fba}. *Return type*|
|\3{background:#ddd}. _Simple @fhiclcpp@ parameters_|
|@Atom<string> label@; |@label()@| @string const&@|
|/2.@Sequence<int> counts@; | @counts()@ | @vector<int>@|
|@counts(1)@ | @int@ |
|/2.@Sequence<double, 3u> point@;| @point()@ | @array<double, 3u>@|
|@point(0)@ | @double@ |
|/3.@Tuple<string, double> assoc;@|@assoc()@| @tuple<string, double>@|
|@assoc.get<0>()@|@string@|
|@assoc.get<double>()@|@double@|
|@Table<Config> config;@|@config()@|@Config const&@|
|\3{background:#ddd}. _Nested @fhiclcpp@ parameters_|
|/2.@Sequence< Sequence<int> > datasets;@ | @datasets()@ | @vector< vector<int> >@ |
| @datasets(17)@ | @vector<int>@ |
|/2.@Sequence< Sequence<int>, 2u > twoDatasets;@ | @twoDatasets()@ | @array< vector<int>, 2u >@ |
|@twoDatasets(1)@ | @vector<int>@ |
|/2.@Sequence< Sequence<int, 2u> > intPairs;@ | @intPairs()@ | @vector< array<int, 2u> >@ |
|@intPairs(42)@ | @array<int, 2u>@|
|/2.@Sequence< Tuple<string, int, bool> > triplets;@ | @triplets()@ | @vector< tuple<string, int, bool> >@ |
|@triplets(3)@ | @tuple<string, int, bool>@ |
|/2.@Sequence< Table<Config> > manyConfigTables;@ | @manyConfigTables()@ | @vector< Config >@ |
|@manyConfigTables(6)@ | @Config const&@ |
|/3.@Tuple< string, Table<Config> > configAssoc;@ | @configAssoc()@ | @tuple< string, Config >@ |
|@configAssoc.get<0>()@ | @string@ |
|@configAssoc.get<1>()@ | @Config@ |
|/3.@Tuple< Tuple<string,bool>, Sequence<int> > awkward;@ | @awkward()@ | @tuple< tuple<string, bool>, vector<int> >@ |
|@awkward.get<0>()@|@tuple<string,bool>@|
|@awkward.get<1>()@|@vector<int>@|

h1(#opt_arg). @Optional@ parameters - argument types

The usage pattern for @Optional@ @fhiclcpp@ parameters is:

<pre><code class="cpp">
OptionalAtom<string> message { Name("message") };

string filled_msg; // passed argument

if ( message(filled_msg) ) {
// use 'filled_msg'
}
</code></pre>

The following table gives the required passed-argument types for a given @Optional@ parameter.

_[ In what follows, @array@, @string@, @tuple@, and @vector@ should each be prefaced with the appropriate namespace resolution: '@std::@'. ]_

|{background:#fba}. *@fhiclcpp@ parameter*|{background:#fba}. *Passed argument*|{background:#fba}. *Function call*|
|\3{background:#ddd}. _Simple @fhiclcpp@ parameters_|
|@OptionalAtom<string> label@; |@string l;@| @bool exists = label(l);@|
|@OptionalSequence<int> counts@; | @vector<int> v;@|@bool exists = counts(v);@ |
|@OptionalSequence<double, 3u> point@;| @array<double, 3u> p;@| @bool exists = point(p);@ |
|@OptionalTuple<string, double> assoc;@|@tuple<string, double> t;@| @bool exists = assoc(t);@|
|@OptionalTable<Config> config;@|@Config c;@|@bool exists = config(c);@|
|\3{background:#ddd}. _Nested @fhiclcpp@ parameters_|
|@OptionalSequence< Sequence<int> > datasets;@ | @vector< vector<int> > sets;@ |@bool exists = datasets(sets);@ |
|@OptionalSequence< Sequence<int>, 2u > twoDatasets;@ | @array< vector<int>, 2u >@ sets; |@bool exists = twoDatasets(sets);@ |
|@OptionalSequence< Sequence<int, 2u> > intPairs;@ | @vector< array<int, 2u> >@ prs; |@bool exists = intPairs(prs);@ |
|@OptionalSequence< Tuple<string, int, bool> > triplets;@ | @vector< tuple<string, int, bool> > trps;@ |@bool exists = triplets(trps);@ |
|@OptionalSequence< Table<Config> > manyConfigTables;@ | @vector< Config > tbls;@ |@bool exists = manyConfigTables(tbls);@ |
|@OptionalTuple< string, Table<Config> > configAssoc;@ | @tuple< string, Config > assoc;@ |@bool exists = configAssoc(assoc);@ |
|@OptionalTuple< Tuple<string,bool>, Sequence<int> > awkward;@ | @tuple< tuple<string, bool>, vector<int> > wow;@ |@bool exists = awkward(wow);@ |

----

h1(#table_func). Additional functions for @Table<T>@

The @Table@ template offers a few extra functions that the user can call:

<pre><code class="cpp">
fhicl::ParameterSet const& get_PSet() const;

void print_allowed_configuration(std::ostream& os,
std::string const& tab = std::string(3,' ') ) const;

// Expert-level functions
void validate_ParameterSet(fhicl::ParameterSet const& pset,
std::set<std::string> const& keysToIgnore = {} );

</code></pre>

h3(#get_pset). @get_PSet@

A call to this function returns a @const@ reference to the @ParameterSet@ object that was used to fill the values of the individual @Table@ members. This is helpful for users who need to interact with the @ParameterSet@ object itself.

h3(#print). @print_allowed_configuration@

For any @Table<Config>@ object, @print_allowed_configuration@ will fill a user-supplied @std::ostream@ object with the allowed configuration as defined by the @Config@ struct. The optional second argument specifies the number of spaces per indentation. The default is 3 spaces but is, of course, user-configurable.

----

%{color:red} _[ *N.B.* The following function should not normally be invoked by users. It is meant to be called only in contexts outside of @art@. Please consult artists@fnal.gov for guidance.]_%

h3(#validate). @validate_ParameterSet@ (expert)

This function is intended for experts who need to validate the @pset@ object themselves. The @keysToIgnore@ variable represents a set of keys for which the validation step will ignore. The validation function will ignore any nested keys as well--i.e. if a user specifies an ignorable key as @table1@, the (e.g.) @table1.someAtom@ key would be ignored in addition to just the @table1@ name. An indexed parameter (e.g.) @seq[1]@ is considered a nested parameter of its parent @seq@. Providing or not providing the ignorable key in a configuration will lead to no error upon validation of the @ParameterSet@.

Should the validation step fail, an exception is thrown of type @fhicl::detail::validationException@. This behavior is not currently configurable.

----

h1(#common_acc). Common parameter accessors

Each of the @fhiclcpp@ types has the following accessors:
<pre><code class="cpp">
std::string key() const;
std::string name() const;
std::string comment() const;
bool has_default() const;
bool is_optional() const;
bool is_conditional() const;
par_type parameter_type() const;
bool should_use() const;
</code></pre>

To call these functions, the difference in syntax is crucial:

<pre><code class="cpp">
Atom<int> val { Name("val") };

auto key1 = val.key(); // correct
auto key2 = val().key(); // ! compile-time ERROR - 'val()' is an int, which has no accessor called 'key()'
</code></pre>

h2. @key()@

A call to @key()@ returns the _full_ key, including all enclosing tables. For example, consider a module that is designed to allow the following configuration:
<pre><code class="ruby">
pset: {
list: [ { particle: electron },
{ particle: muon } ]
}
</code></pre>For a suitably declared set of @fhiclcpp@ parameters, the returned key corresponding to "muon" would be @pset.list[1].particle@.

h2. @name()@

The name is the most-nested name in the key. For the above "muon" parameter, a key of @pset.list[1].particle@ has a corresponding name of @particle@. If the parameter in question were @pset.list[1]@, the name would be[1] @list[1]@.

fn1. Technically, this is inaccurate -- sequence elements do not have names. However, for the sake of parameter identification, a sequence element has a name whose value is the sequence name with the appropriate sequence element index/indices appended.

h2. @comment()@

Returns the comment supplied as the string literal in (e.g.) @Comment("Here is the comment")@. If no @Comment@ argument is provided in the @fhiclcpp@ parameter constructor, a call to this function returns an empty string.

h2. @has_default()@

Returns @true@ or @false@ depending on whether the user supplied a default value for the parameter.

h2. @is_optional()@

Returns @true@ if the parameter is an @Optional*@ @fhiclcpp@ type; @false@ otherwise.

h2. @is_conditional()@

Returns @true@ if a configuration predicate (either through @fhicl::use_if@, @fhicl::use_unless@, or some supplied lambda function) has been provided by the user; @false@ otherwise.

h2. @parameter_type()@

Returns an enumeration value based on the parameter type:

<pre><code class="cpp">
enum class par_type {
ATOM, // (Optional)Atom<T>
TABLE, // (Optional)Table<T>
SEQ_VECTOR, // (Optional)Sequence<T>
SEQ_ARRAY, // (Optional)Sequence<T,std::size_t>
TUPLE, // (Optional)Tuple<T...>
NTYPES // Signifies invalid parameter
};
</code></pre>

h2. @should_use()@

Returns @true@ unless a user-provided configuration predicate returns @false@.