Project

General

Profile

Wiki » History » Version 29

« Previous - Version 29/48 (diff) - Next » - Current version
Christopher Green, 04/04/2014 01:40 PM


Wiki

Contents

Library overview

The fhiclcpp library provides types and functions that constitute a binding of the FHiCL specification to C++. (See https://cdcvs.fnal.gov/redmine/attachments/5348/quick_start.pdf for an introduction to FHiCL nomenclature and concepts.)

The following types are provided, each declared in the fhicl namespace:

  • ParameterSet, corresponding to a user-specified configuration (a "collection of named values accessible to a user’s program while it is running");
  • ParameterSetID, uniquely identifying a specific value of a ParameterSet instance;
  • ParameterSetRegistry, automatically registering each ParameterSet instance (or sub-instance) with its corresponding ParameterSetID;
  • intermediate_table, serving as an internal ("raw" or "working") representation of a FHiCL document;
  • extended_value, representing a FHiCL value within an intermediate_table;
  • value_tag, classifying an extended_value instance; and
  • exception, describing a circumstance from which the library can't recover.

In addition, the library provides public member functions and (also in the fhicl namespace) free functions to construct, observe, and transform values of these types.

The next section details the interface of the ParameterSet type, likely of greatest interest to most users of this library. (A separate page describes those remaining types and functions that are typically used only while initially producing ParameterSet instances by combining information obtained from a fhicl document with additional information from such sources as a command line and application-specific defaults.)

The ParameterSet interface

Names, keys, and values

  • In the descriptions below, parameters and arguments denoted name are always of type of type std::string; each corresponds to FHiCL's notion of a name.
  • In the descriptions below, parameters and arguments denoted key are always of type of type std::string; each also corresponds to FHiCL's notion of a name, but when one ParameterSet is nested within another ParameterSet, a key may employ the FHiCL member notation.
  • Each ParameterSet object consists of some number of keys, each associated with a value of some C++ type. Such an association is termed a key-value pair. When the key is a simple name, the association is equivalently termed a name-value pair.
  • A value can be retrieved from a ParameterSet by presenting its corresponding key. Similarly, a value can be inserted into a ParameterSet by presenting both the value and its desired corresponding key.
  • A ParameterSet contains values of C++ types closely corresponding to FHiCL values. We refer to the C++ types in the following list as FHiCL types.
    • The C++ standard bool type corresponds to FHiCL's notion of a boolean value.
    • The C++ standard signed and unsigned integer types, as well as the C++ standard floating-point types, correspond to FHiCL's notion of a numeric value.
    • The C++ std::complex<> types correspond to FHiCL's notion of a complex value.
    • The C++ std::string type corresponds to FHiCL's notion of a string value.
    • The C++ std::vector types correspond to FHiCL's notion of a sequence value. Only homogeneous sequences are supported in this binding.
    • The fhicl::ParameterSet type corresponds to FHiCL's notion of a table value. Note that a processed FHiCL document also yields a ParameterSet.
  • As an extension to the functionality required of a FHiCL binding, a ParameterSet can contain values of arbitrary user-defined C++ types. The library processes such values via user-supplied functions that convert to the user-defined type. (In practice, this has been a rarely-used fhiclcpp library feature.)

Relationship to ParameterSetID

  • A ParameterSetID is automatically generated from (and thus corresponds to) the value of a ParameterSet object.
  • If the value of a ParameterSet object ps is modified in any way (whether by inserting, deleting, or updating any key-value pair), a new ParameterSetID value is generated to correspond to the updated value of ps.

Immutability

In practice, most ParameterSet objects, once constructed, are treated as immutable. While such practice is not required, it is preferable because of the relationship of a ParameterSet to a ParameterSetID, described above.

Compiler-generated functions

  • A default-constructed ParameterSet object is empty; that is, it consists of no key-value pairs.
  • A copy-constructed ParameterSet object has the same key-value pairs as did the ParameterSet object from which it was copied.
  • A newly assigned-to ParameterSet object has the same key-value pairs as did the ParameterSet object from which it was copied.

Observers

  • A call of the form ps.is_empty() returns true if ps is empty, and returns false otherwise.
  • A call of the form ps.id() returns the ParameterSetID value corresponding to the current value of ps.
  • A call of the form ps.tostring() returns a compact std::string representation of the current value of ps.
  • A call of the form ps.to_indented_string(unsigned initial_indent_level = 0) returns an expanded and easier-to-read std::string representation of the current value of ps.
  • A call of the form ps.get_keys() returns, as a std::vector<std::string>, a list of all names in ps.
  • A call of the form ps.get_pset_keys() returns, as a std::vector<std::string>, a list of all names in ps whose corresponding values are of ParameterSet type.

Retrievers

  • A call of the form ps.get<T>(key) (or of the variant form ps.get<T>(key, convert)) will return the value of type T associated with the key.
    • Either call will throw an exception if:
      • ps contains no pair with a matching key, or
      • ps does contain a pair with a matching key, but the corresponding value can't be returned as a value of type T.
    • The first form is used when the type T is corresponds to a FHiCL value.
    • The variant form is used when T is an arbitrary user-defined type. The convert argument is a user-provided function that converts a given FHiCL value to a value of type T.
  • A call of the form ps.get(key,default_value) (or of the variant form ps.get<T>(key, default_value, convert)) will return the value of type T associated with the key.
    • The first form is used when the type T is corresponds to a FHiCL value.
    • The variant form is used when T is an arbitrary user-defined type. The convert argument is a user-provided function that converts a given FHiCL value to a value of type T.
    • Either call will return the supplied default_value (which must be of type T) if:
      • ps contains no pair with a matching key, or
      • ps does contain a pair with a matching key, but the corresponding value can't be returned as a value of type T.
  • A call of the form get_if_present(key, result) (or of the variant form get_if_present(key, result, convert)) has the following behavior:
    • If the supplied key is an empty string, throw an exception.
    • If ps contains no pair with a matching key, return false.
    • If ps does contain a pair with a matching key, but the corresponding value isn't of type T, throw an exception.
    • Otherwise, set the supplied result (which must be an lvalue expression) to the corresponding value and return true.
    • The first form is used when the type T is corresponds to a FHiCL value.
    • The variant form is used when T is an arbitrary user-defined type. The convert argument is a user-provided function that converts a given FHiCL value to a value of type T.

Inserters

  • A call of the form ps.put(name, value) will insert into ps a name-value pair composed of the given name and the given value.
    • If ps already contains a pair with the given name, that pair's value component is replaced by the value provided in the call.
    • Otherwise, a new pair is constructed and inserted into ps.
    • The type of the supplied value must be a FHiCL type. If it is not, either the code will fail to compile or else the compiled code will throw an exception.
  • A call of the form ps.put(name) will insert into ps a name-value pair composed of the given name and the library's equivalent of a FHiCL nil value.
    • If ps already contains a pair with the given name, that pair's value component is replaced.
    • Otherwise, a new pair is constructed and inserted into ps.
  • A call of the form ps.insert(name, value) will insert into ps a name-value pair composed of the given name and the given value.
    • If ps already contains a pair with the given name, that pair's value component is replaced.
    • Otherwise, a new pair is constructed and inserted into ps.
    • The supplied value may be of any C++ type and will be inserted as-is (i.e., will be treated strictly as a user-defined type). It is therefore recommended that this call not be used with values of any FHiCL type.

Deleters

A call of the form ps.erase(name) will attempt to remove from ps the name-value pair with matching name and will return true if successful and false otherwise (i.e., if ps contains no pair with the specified name).

Comparators

Two ParameterSet objects may be compared for equality or inequality via the corresponding conventional operator notations. The objects are considered equal if and only if their respective ParameterSetID values are equal.

Interface technical summary

class ParameterSet
{
public:
  // use compiler-generated default c'tor, d'tor, and copy functions

  // observers:
  bool                      is_empty          ( ) const;
  ParameterSetID            id                ( ) const;
  std::string               to_string         ( ) const;
  std::string               to_indented_string( ) const;
  std::vector<std::string>  get_keys          ( ) const;
  std::vector<std::string>  get_pset_keys     ( ) const;

  // retrievers:
  template< class T >
    bool get_if_present( std::string const & key, T & value ) const;
  template< class T, class Via >
    bool get_if_present( std::string const & key, T & value, T convert(Via const &) ) const;
  template< class T >
    T  get( std::string const & key ) const;
  template< class T, class Via >
    T  get( std::string const & key, T convert(Via const &) ) const;
  template< class T >
    T  get( std::string const & key, T const & default_value ) const;
  template< class T, class Via >
    T  get( std::string const & key, T const & default_value, T convert(Via const &) ) const;

  // inserters:
  void  insert( std::string const & name, boost::any const & value );
  void  put( std::string const & name );  // implicit nil value
  template< class T >
    void  put( std::string const & name, T const & value );

  // deleters:
  bool  erase( std::string const & name );

  // comparators:
  bool  operator == ( ParameterSet const & other ) const;
  bool  operator != ( ParameterSet const & other ) const;

};  // ParameterSet