1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// *****************************************************************************
/*!
  \file      src/Control/HelpFactory.hpp
  \copyright 2012-2015 J. Bakosi,
             2016-2018 Los Alamos National Security, LLC.,
             2019-2021 Triad National Security, LLC.
             All rights reserved. See the LICENSE file for details.
  \brief     Command-line and input deck help factory
  \details   This file contains some types that facilitate the generation of
     on-screen help.
*/
// *****************************************************************************
#ifndef HelpFactory_h
#define HelpFactory_h

#include <brigand/sequences/list.hpp>
#include <brigand/algorithms/for_each.hpp>

#include "PUPUtil.hpp"
#include "Factory.hpp"
#include "Has.hpp"
#include "Types.hpp"

namespace tk {
namespace ctr {

//! \brief Keyword information bundle
//! \details This bundle contains the information that is used to display
//!    on-screen help on all command-line arguments and control file keywords
//!    for an exectuable. This struct is stored in a container that associates
//!    keywords (used by a grammar and parser) to this struct. The container, an
//!    runtime, std::map, is filled by the CmdLine and InputDeck objects'
//!    constructors by one or more brigand::for_each which loops through the
//!    set of all keywords used in a grammar. The maps are stored in the CmdLine
//!    and InputDeck objects (which are tagged tuples) and thus can be migrated
//!    through the network, thus the Charm++ parck/unpack routines are defined.
//! \see Info functor used to fill the std::maps
struct KeywordInfo {
  std::string shortDescription;           //!< Short description
  std::string longDescription;            //!< Long description
  std::optional< std::string > alias;     //!< Keyword alias
  std::optional< std::string > expt;      //!< Expected type description
  std::optional< std::string > lower;     //!< Lower bound as string
  std::optional< std::string > upper;     //!< Upper bound as string
  std::optional< std::string > choices;   //!< Expected choices description

  /** @name Pack/Unpack: Serialize KeywordInfo object for Charm++ */
  ///@{
  //! \brief Pack/Unpack serialize member function
  //! \param[in,out] p Charm++'s PUP::er serializer object reference
  void pup( PUP::er& p ) {<--- Parameter 'p' can be declared with const
    p | shortDescription;
    p | longDescription;
    p | alias;
    p | expt;
    p | lower;
    p | upper;
    p | choices;
  }
  //! \brief Pack/Unpack serialize operator|
  //! \param[in,out] p Charm++'s PUP::er serializer object reference
  //! \param[in,out] info KeywordInfo object reference
  friend void operator|( PUP::er& p, KeywordInfo& info ) { info.pup(p); }
  ///@}
};

//! \brief A typedef for associating a keyword-string with its associated
//!   information stored in a KeywordInfo struct
using HelpFactory = std::map< std::string, KeywordInfo >;

//! \brief Help bundle on a single keyword
//! \details This is used for delivering help on a single keyword. This struct
//!    also differentiates between command-line arguments and control file
//!    keywords.
struct HelpKw {
  HelpFactory::key_type keyword;        //!< Keyword string
  HelpFactory::mapped_type info;        //!< Keyword information
  bool cmd;                             //!< True if command-line keyword

  /** @name Pack/Unpack: Serialize HelpKw object for Charm++ */
  ///@{
  //! \brief Pack/Unpack serialize member function
  //! \param[in,out] p Charm++'s PUP::er serializer object reference
  void pup( PUP::er& p ) { p|keyword; p|info; p|cmd; }<--- Parameter 'p' can be declared with const
  //! \brief Pack/Unpack serialize operator|
  //! \param[in,out] p Charm++'s PUP::er serializer object reference
  //! \param[in,out] h HelpKw object reference
  friend void operator|( PUP::er& p, HelpKw& h ) { h.pup(p); }
  ///@}
};

//! \brief Function object for filling a HelpFactory (std::map) with keywords
//!   and their associated information bundle
//! \details This struct is used as a functor to loop through a set of keywords
//!   at compile-time and generate code for filling up the std::map.
struct Info {
  //! Store reference to map we are filling
  tk::ctr::HelpFactory& m_factory;
  //! Constructor: store reference to map to fill
  explicit Info( tk::ctr::HelpFactory& factory ) : m_factory( factory ) {}
  //! \brief Function call operator templated on the type that does the filling
  template< typename U > void operator()( brigand::type_<U> ) {
    m_factory[ U::string() ] = { U::shortDescription(),
                                 U::longDescription(),
                                 U::alias(),
                                 U::expt(),
                                 U::lower(),
                                 U::upper(),
                                 U::choices() };
  }

  //! Fill map in a simpler way passing a string rather than a brigand-type
  void fill( const tk::entry_t& kw )
  {
    m_factory[kw.string()] = { kw.shortDescription(),
                               kw.longDescription(),
                               kw.alias(),
                               kw.expt(),
                               kw.lower(),
                               kw.upper(),
                               kw.choices() };
  }
};

} // ctr::
} // tk::

#endif // HelpFactory_h